<template>
    <div class="context" v-loading="canvasLoading">
  
        <div style="height: 0px;">
            <span style="font-family:SourceHanSansK-Bold ;font-size: 0px;">分</span>
            <img class="drawImg" id="qrCode" />
            <img class="drawImg" id="barCode" />
            <label v-for="(v,i) in pathList" :key="i">
                <img class="drawImg" :id="gernerteId(v.id)" />
            </label>
            <!-- uploadCanvas是上传图片时暂时使用的canvas，是为了变成和画布相同的颜色 -->
            <canvas id="uploadCanvas" style="position: fixed;left: 100vw;"></canvas>
        </div>
        <!-- 取消重置那一栏 -->
        <div style="height: 50px;border-bottom: 1px solid #FFFFFF;">
            <el-col :span="24" style="height: 50px;">
                <div class="grid-content bg-purple-dark" style="height: 50px;background: #d0dce6;">
                    <el-row style="text-align: left;padding-top: 6px;">
                        <el-button size="mini" @click="goBack()" style="margin-left: 10px;">
                            <img :src="iconListLoaded.back" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="clearCanvas()">
                            <img :src="iconListLoaded.clear" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="alignUp()">
                            <img :src="iconListLoaded.topAlign" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="alignDown()">
                            <img :src="iconListLoaded.bottomAlign" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="alignLeft()">
                            <img :src="iconListLoaded.leftAlign" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="alignCenter()">
                            <img :src="iconListLoaded.centerAlign" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="alignRight()">
                            <img :src="iconListLoaded.rightAlign" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="levelUp()">
                            <img :src="iconListLoaded.topestLevel" style="width: 28px;" />
                        </el-button>
                        <el-button size="mini" @click="levelDown()">
                            <img :src="iconListLoaded.lowestLevel" style="width: 28px;" />
                        </el-button>
                        <el-button size="mini" @click="preview()">
                            <img :src="iconListLoaded.preview" style="width: 20px;" />
                        </el-button>
                        <el-button size="mini" @click="saveCanvas()">
                            <img :src="iconListLoaded.save" style="width: 20px;" />
                        </el-button>

                        <el-button size="mini" @click="saveAsBmp()" style="height: 34px;position: relative; ">保存为BMP</el-button>

                        <el-upload 
                            multiple 
                            action="fileUrl" 
                            :limit="limitNum" 
                            :file-list="fileList"
                            :before-upload="beforeUpload" 
                            accept=".json" 
                            :on-success="onSuccess"
                            :show-file-list="showFileList" 
                            :http-request="uploadJSON"
                            style="display: inline-block;"
                        >
                            <el-button size="mini" style="height: 34px;position: relative;margin: 0 10px; ">导入JSON</el-button>
                        </el-upload>

                        <!-- <el-button size="mini" @click="importJSON()" style="height: 34px;position: relative; ">导入JSON</el-button> -->
                        <el-button size="mini" @click="exportAsJSON()" style="height: 34px;position: relative; ">导出为JSON</el-button>
                        <el-button size="mini" @click="canvasUndo()" 
                            :disabled="crtUndoIndex <= 0" 
                            style="height: 34px;position: relative; ">
                        撤销</el-button>
                        <el-button size="mini" @click="canvasForward()" 
                            :disabled="this.undoStock.length === 0 || this.crtUndoIndex === this.undoStock.length - 1" 
                            style="height: 34px;position: relative; ">
                        前进</el-button>
                        <div class="demo-image__preview" style="display:none">
                            <el-image ref="previewUrl" :src="url" :preview-src-list="srcList">
                            </el-image>
                        </div>
                    </el-row>
                </div>
            </el-col>
        </div>
        <el-row style="height:calc(100% - 50px);">
            <div style="height: 100%;overflow:auto;background-color: #FFF;width: 240px;float: left;padding: 20px;box-sizing: border-box;">

                <el-collapse v-model="activeNames" @change="handleChange">
                    <el-collapse-item title="公共组件" name="1">
                        <div>
                            <div class="base_contro" @click="addRect()">
                                <span class="base_contro_icon">
                                    <canvas id="iconRect" width="32" height="32"></canvas>
                                </span>
                                <span>矩形</span>
                            </div>
                            <div class="base_contro" @click="addRoundRect()">
                                <span class="base_contro_icon">
                                    <canvas id="iconRoundRect" width="32" height="32"></canvas>
                                </span>
                                <span>圆角矩形</span>
                            </div>
                            <div class="base_contro" @click="addArc()">
                                <span class="base_contro_icon">
                                    <canvas id="iconArc" width="32" height="32"></canvas>
                                </span>
                                <span>圆形</span>
                            </div>
                            <div class="base_contro" @click="addLine()">
                                <span class="base_contro_icon">
                                    <canvas id="iconLine" width="32" height="32"></canvas>
                                </span>
                                <span>直线</span>
                            </div>
                            <div class="base_contro" @click="addQrCode()">
                                <span class="base_contro_icon">
                                    <canvas id="iconQrCode" width="32" height="32"></canvas>
                                </span>
                                <span>二维码</span>
                            </div>
                            <div class="base_contro" @click="addBarCode()">
                                <span class="base_contro_icon">
                                    <canvas id="iconBarCode" width="32" height="32"></canvas>
                                </span>
                                <span>条形码</span>
                            </div>
                            <div class="base_contro" @click="addEmptyText()">
                                <span class="base_contro_icon">
                                    <!-- <canvas id="iconTextCode" width="32" height="32"></canvas> -->
                                    <img style="width: 32px; height: 34px;" :src="getTextUrl()" />
                                </span>
                                <div style="margin-top: 4px;">文本</div>
                            </div>
                            <div class="base_contro" @click="addEmptyNumber()">
                                <span class="base_contro_icon">
                                    <img style="width: 32px; height: 38px;" :src="getNumberUrl()" />
                                </span>
                                <span>数字</span>
                            </div>
                            <div class="base_contro" @click="addEmptyDate()">
                                <span class="base_contro_icon">
                                    <img style="width: 32px; height: 32px;" :src="getDateUrl()" />
                                    <!-- <canvas id="iconDateCode" width="32" height="32"></canvas> -->
                                </span>
                                <span>日期</span>
                            </div>
                            <div class="base_contro" @click="addEmptyTime()">
                                <span class="base_contro_icon">
                                    <img style="width: 32px; height: 32px;" :src="getTimeUrl()" />
                                    <!-- <canvas id="iconTimeCode" width="32" height="32"></canvas> -->
                                </span>
                                <span>时间</span>
                            </div>
                            <div class="base_contro">
  
                                <el-upload multiple action="fileUrl" :limit="limitNum" :file-list="fileList"
                                    :before-upload="beforeUpload" accept=".png" :on-success="onSuccess"
                                    :show-file-list="showFileList" :http-request="uploadFile">
                                    <span class="base_contro_icon">
                                        <i style="font-size: 32px;line-height: 24px;" class="el-icon-upload"></i>
                                    </span>
                                    <span id="uploadPic">上传</span>
                                </el-upload>
                            </div>
                            <div class="base_contro">
                                <el-upload multiple action="fileUrl" :limit="limitNum" :file-list="fileList"
                                    :before-upload="beforeUpload" accept=".zip" :on-success="onSuccess"
                                    :show-file-list="showFileList" :http-request="uploadZip">
                                    <span class="base_contro_icon">
                                        <i style="font-size: 32px;line-height: 24px;" class="el-icon-upload"></i>
                                    </span>
                                    <span id="uploadZip">随机图</span>
                                </el-upload>
                            </div>
  
                        </div>
  
                    </el-collapse-item>
                    <el-collapse-item title="组件列表" name="2">
                        <div class="title-list">
                            <div
                                v-dragging="{item: item, list: pathList}"
                                v-for="item in pathList"
                                :key="item.id"
                                class="title-item"
                            >
                                <div class="title-child">
                                    <span>{{item.id +"－－"+ item.other }}</span>
                                </div>
                            </div>
                        </div>
                    </el-collapse-item>
  
                </el-collapse>
                <!-- <div style="height: 100%;" class="grid-content bg-purple">
                    <el-button @click="maxScale()">放大</el-button>
                    <el-button @click="minScale()">缩小</el-button>
                </div> -->
            </div>
            <div style="height: 100%;overflow:auto;width:calc(100% - 480px);float: left;">
                <div class="grid-content bg-purple-light" style="height: 100%;position: relative;" @click.self="clearSelect">
                    <div :style="{ width: canvasWidth + 'px', margin : '0 auto', overflow: 'hidden' }">
                        <div ref="topRulerBoxRef" style="overflow: hidden;">
                            <ruler-drag
                                v-if="rulerWidthSize > 0"
                                :size="rulerWidthSize"
                                :step="100"
                                direction="up"
                                :style="{'width':rulerWidthSize * 100 + 'px', height: `36px`}"
                                ref="topRulerRef"
                            ></ruler-drag>
                        </div>
                    </div>
                    <div class="left-ruler"
                        style="position: absolute; width: 60px;"
                        ref="leftRulerBoxRef"
                        :style="{ height: canvasHeight + 10 + 'px', left: rulerLeftVal + 'px', overflow: 'hidden' }"
                        >
                        <ruler-drag
                            v-if="rulerHeightSize > 0"
                            :size="rulerHeightSize"
                            :step="100"
                            direction="right"
                            :style="{ height: rulerHeightSize * 100 + 'px', marginTop: '10px' }"
                            ref="leftRulerRef"
                        ></ruler-drag>
                    </div>
                    <div :style="{'width':canvasWidth+'px'}" style="margin:auto;">
                        <el-input 
                            v-model="pathList[canvasIndex].content" 
                            v-if="canvasIndex > -1 && pathList[canvasIndex].valueType == 'text' && clickItem3times >= 3"
                            style="position: absolute;"
                            :style="{ width: canvasIpt.w + 'px', height: canvasIpt.h + 'px', top: canvasIpt.t + 'px', left: canvasIpt.l + 'px' }"
                        />
                        <el-date-picker 
                            size="mini" 
                            type="date"
                            v-model="pathList[canvasIndex].content"
                            @change="updateCanvas()"
                            v-if="canvasIndex > -1 && pathList[canvasIndex].valueType == 'date' && clickItem3times >= 3"
                            style="position: absolute;"
                            :style="{ width: canvasIpt.w + 'px', height: canvasIpt.h + 'px', top: canvasIpt.t + 'px', left: canvasIpt.l + 'px' }"
                        >
                        </el-date-picker>
                        <!-- <el-input-number 
                            v-model="pathList[canvasIndex].content"
                            @change="updateCanvas()"
                            v-show="canvasIndex > -1 && pathList[canvasIndex].valueType == 'number' && clickItem3times >= 3"
                            style="position: absolute;"
                            :style="{ width: canvasIpt.w + 'px', height: canvasIpt.h + 'px', top: canvasIpt.t + 'px', left: canvasIpt.l + 'px' }"
                        >
                        </el-input-number> -->
                        <el-time-picker 
                            size="mini"
                            type="date" 
                            @change="updateCanvas()" 
                            v-model="pathList[canvasIndex].tempContent"
                            v-if="canvasIndex > -1 && pathList[canvasIndex].valueType == 'time' && clickItem3times >= 3"
                            style="position: absolute;"
                            :style="{ width: canvasIpt.w + 'px', height: canvasIpt.h + 'px', top: canvasIpt.t + 'px', left: canvasIpt.l + 'px' }"
                        >
                        </el-time-picker>
                        <div style="height: 10px;" ref="ctxTopDivRef"></div><!-- 撑高度的 -->
                        <canvas id="canvas" :width="canvasWidth" :height="canvasHeight" ref="canvasRef" @mouseout="mouseup($event)"
                            @mousewheel="mousewheel($event)" @mouseup="mouseup($event)" @mousemove="mouseMove($event)"
                            @mousedown="mousedown($event)"></canvas>
                    </div>
                </div>
            </div>
            <div style="height: 100%;overflow:auto;width: 240px;float: left;" :style="{ display: canvasIndex > -1 ? 'block': 'none' }" @keyup.stop @mousewheel.stop>
                <div class="grid-content bg-purple " style="height: 100%;background: #FFFFFF;box-sizing: border-box;padding: 20px;">
                    <el-tabs v-model="activeName" class="my_content" style="height: 100%;overflow: hidden;">
  
                        <el-tab-pane :label="getProperty()" name="first" style="height: 100%;">
  
                            <label v-if="canvasIndex>-1" style="height: 100%;">
                                <div style="min-height: 50px;"
                                    v-if="pathList[canvasIndex].module=='A'&&pathList[canvasIndex].type==7">
                                    <div class="property">
                                        内容</div>
                                    <div class="property_div" >
                                        <el-input readonly="readonly" type="textarea" :autosize="{ minRows: 2, maxRows: 10 }" @input="updateCanvas()"
                                            placeholder="请输入内容" v-model="pathList[canvasIndex].content">
                                        </el-input>
                                        <el-button @click="uploadAgain()" style="float: right;margin-top: 5px;"
                                            type="primary" size="mini">重新上传</el-button>
                                    </div>
  
                                </div>
                                <div style="min-height: 40px;" v-if="pathList[canvasIndex].module=='B'" key="content">
                                    <div class="property">
                                        内容
                                    </div>
                                    <div class="property_div"  style="margin-bottom: 10px;" v-if="pathList[canvasIndex].valueType == 'text'">
                                        <el-input type="textarea" autosize @input="updateCanvas()" placeholder="请输入内容"
                                            v-model="pathList[canvasIndex].content">
                                        </el-input>
                                    </div>
                                    <div class="property_div"  style="margin-bottom: 10px;" v-if="pathList[canvasIndex].valueType == 'number'">
                                        <el-input-number size="mini" @change="updateCanvas()" placeholder="请输入内容"
                                            v-model="pathList[canvasIndex].content">
                                        </el-input-number>
                                    </div>
                                    <div class="property_div"  style="margin-bottom: 10px;" v-if="pathList[canvasIndex].valueType == 'date'">
                                        <el-input v-show="false"/>
                                        <el-date-picker size="mini" type="date" @change="updateCanvas()" placeholder="请输入内容"
                                            v-model="pathList[canvasIndex].content">
                                        </el-date-picker>
                                    </div>
                                    <div class="property_div"  style="margin-bottom: 10px;" v-if="pathList[canvasIndex].valueType == 'time'">
                                        <el-input v-show="false"/>
                                        <el-time-picker size="mini" type="date" @change="updateCanvas()" placeholder="请输入内容"
                                            v-model="pathList[canvasIndex].tempContent">
                                        </el-time-picker>
                                    </div>
                                </div>

                                <div style="height: 35px;"
                                    v-if="pathList[canvasIndex].module=='A'&&(pathList[canvasIndex].type==5||pathList[canvasIndex].type==6)">
                                    <div class="property">
                                        内容</div>
                                    <div class="property_div" >
                                        <el-input type="textarea" autosize @input="updateCanvas($event, 'content')"
                                            placeholder="请输入内容" v-model="pathList[canvasIndex].content">
                                        </el-input>
  
                                    </div>
  
                                </div>

                                <div style="height: 35px;"
                                    v-if="pathList[canvasIndex].module=='A' && pathList[canvasIndex].type == 7 ">
                                    <div class="property">
                                        开启抖动
                                    </div>
                                    <div class="property_div" >
                                        <!-- <el-input type="textarea" autosize @input="updateCanvas($event, 'content')"
                                            placeholder="请输入内容" v-model="pathList[canvasIndex].content">
                                        </el-input> -->
                                        <el-switch
                                            v-model="pathList[canvasIndex].isShake"
                                            active-color="#13ce66" @change="updateCanvas($event, 'isShake')"
                                            inactive-color="#cccccc">
                                        </el-switch>
                                    </div>
  
                                </div>

                                <div style="height: 35px;"
                                    v-if="
                                        (pathList[canvasIndex].module=='B'&&(pathList[canvasIndex].valueType == 'text')) 
                                        ||
                                        (pathList[canvasIndex].module=='A'&&(
                                            pathList[canvasIndex].type == 5 || pathList[canvasIndex].type == 6
                                        ))
                                    ">
                                    <div class="property">
                                        变量名
                                    </div>
                                    <div class="property_div" >
                                        <el-input v-show="false" />
                                        <el-input type="textarea" autosize size="mini" @input="updateCanvas($event)"
                                            placeholder="请输入内容" v-model.trim="pathList[canvasIndex].varName">
                                        </el-input>
  
                                    </div>
                                </div>

                                <div style="height: 35px;"
                                    v-if="
                                        (pathList[canvasIndex].module=='A'&&(pathList[canvasIndex].type == 5))
                                    ">
                                    <div class="property">
                                        色块大小
                                    </div>
                                    <div class="property_div" >
                                        <el-input v-show="false" />
                                        <el-input-number type="textarea" autosize size="mini" @input="updateCanvas($event)"
                                            placeholder="请输入内容" v-model.trim="pathList[canvasIndex].moduleSize">
                                        </el-input-number>
  
                                    </div>
                                </div>
  
                                <div v-if="pathList[canvasIndex].module=='A'&&pathList[canvasIndex].type<4"
                                    style="height:35px;">
                                    <div class="property">
                                        填充</div>
                                    <div class="property_div" >
                                        <el-input v-show="false"/>
                                        <el-radio-group @change="updateCanvas()" size="mini"
                                            v-model="pathList[canvasIndex].full">
                                            <el-radio-button label="1">是</el-radio-button>
                                            <el-radio-button label="2">否</el-radio-button>
  
                                        </el-radio-group>
  
                                    </div>
  
                                </div>
                                <div v-if="
                                     ( pathList[canvasIndex].module=='A' && pathList[canvasIndex].type<4 && pathList[canvasIndex].full == 2 ) 
                                     || ( pathList[canvasIndex].module =='A' && pathList[canvasIndex].type == 4 )
                                    "
                                    style="height:35px;">
                                    <div class="property">
                                        边框宽度</div>
                                    <div class="property_div" >
                                        <el-input v-show="false"/>
                                        <el-input-number type="textarea" autosize size="mini" @input="updateCanvas($event)"
                                            placeholder="请输入内容" v-model.trim="pathList[canvasIndex].lineWidth">
                                        </el-input-number>
                                    </div>
                                </div>

                                <div v-if="
                                     ( pathList[canvasIndex].module =='A' && pathList[canvasIndex].type == 4 )
                                    "
                                    style="height:35px;">
                                    <div class="property">
                                        斜率</div>
                                    <div class="property_div" >
                                        <el-input v-show="false"/>
                                        <el-select size="mini" style="width: 130px;"
                                            v-model="pathList[canvasIndex].slope" placeholder="请选择" @change="updateCanvas()">
                                            <el-option label="反斜线" value="-1"></el-option>
                                            <el-option label="平线" value="0"></el-option>
                                            <el-option label="斜线" value="1"></el-option>
                                        </el-select>
                                    </div>
                                </div>

                                <div v-if="(pathList[canvasIndex].module=='A'&&pathList[canvasIndex].type<5)||(pathList[canvasIndex].module=='B')"
                                    style="height:35px;">
                                    <div class="property">
                                        颜色</div>
                                    <div class="property_div" >
                                        <el-input v-show="false"/>
                                        <el-radio-group @change="updateCanvas()" size="mini"
                                            v-model="pathList[canvasIndex].color">
                                            <!-- <el-radio-button :label="color.value" v-for="color in colorList" :key="color.label" size="mini">{{ color.label }}</el-radio-button> -->
                                            
                                                <el-radio-button label="#000000">黑</el-radio-button>
                                                <el-radio-button label="#FFFFFF">白</el-radio-button>
                                                <el-radio-button label="#C00000" v-if="params.type == 1">红</el-radio-button> 
                                                <el-radio-button label="#FFC000" v-if="params.type == 2">黄</el-radio-button> 
                                        </el-radio-group>
  
                                    </div>
  
                                </div>
                                <div v-if="pathList[canvasIndex].module=='A'&&pathList[canvasIndex].type == 2"
                                    style="height:35px;">
                                    <div class="property">
                                        圆角半径
                                    </div>
                                    <div class="property_div" >
                                        <el-input v-show="false"/>
                                        <el-input-number @change="updateCanvas()" size="mini" style="width: 140px;"
                                            v-model="pathList[canvasIndex].r" :min="0" :max="Math.min(pathList[canvasIndex].w, pathList[canvasIndex].h)">
                                        </el-input-number>
                                    </div>
  
                                </div>
                                <div v-if="pathList[canvasIndex].module=='B'"
                                    style="height:35px;">
                                    <div class="property">
                                        底色
                                    </div>
                                    <div class="property_div" >
                                        <el-radio-group @change="updateCanvas();onBaseColorChange(canvasIndex)" size="mini"
                                            v-model="pathList[canvasIndex].baseColor">
                                            <!-- <el-radio-button :label="color.value" v-for="color in colorList" :key="color.label">{{ color.label }}</el-radio-button> -->
                                            <el-radio-button label="#000000">黑</el-radio-button>
                                            <el-radio-button label="#FFFFFF">白</el-radio-button>
                                            <el-radio-button label="#C00000" v-if="params.type == 1">红</el-radio-button> 
                                            <el-radio-button label="#FFC000" v-if="params.type == 2">黄</el-radio-button> 
                                        </el-radio-group>
  
                                    </div>
  
                                </div>
                                <div style="height: 35px;"
                                    v-if="pathList[canvasIndex].module=='B'" key="fontSize">
                                    <div class="property">
                                        字体大小</div>
                                    <div class="property_div" >
                                        <el-input-number @change="updateCanvas()" size="mini" style="width: 140px;"
                                            v-model="pathList[canvasIndex].fontSize" :min="10" label="描述文字">
                                        </el-input-number>
  
                                    </div>
  
                                </div>
                                <div style="min-height: 120px;"
                                    v-if="pathList[canvasIndex].module=='B'">
                                    <div class="property">
                                        字体样式
                                    </div>
                                    <div class="property_div" >
                                        <div style="height: 40px;">
                                            <el-button type="primary" @click="editFontStyle(1)" class="font_style"
                                                v-if="pathList[canvasIndex].bold=='1'" size="mini">粗体</el-button>
                                            <el-button class="font_style" @click="editFontStyle(1)"
                                                v-if="pathList[canvasIndex].bold=='2'" size="mini">粗体</el-button>
                                            <el-button type="primary" v-if="pathList[canvasIndex].italic=='1'"
                                                @click="editFontStyle(2)" class="font_style" size="mini">斜体</el-button>
                                            <el-button v-if="pathList[canvasIndex].italic=='2'"
                                                @click="editFontStyle(2)" class="font_style" size="mini">斜体</el-button>
                                            <el-button type="primary" v-if="pathList[canvasIndex].removeLine=='1'"
                                                class="font_style" @click="editFontStyle(3)" size="mini">删除线</el-button>
                                            <el-button class="font_style" @click="editFontStyle(3)"
                                                v-if="pathList[canvasIndex].removeLine=='2'" size="mini">删除线</el-button>
                                        </div>
                                        <div style="height: 40px;">
                                            <el-button @click="editFontStyle(4,1)" class="font_style" type="success"
                                                v-if="pathList[canvasIndex].textAlign=='1'" size="mini">居左</el-button>
                                            <el-button @click="editFontStyle(4,1)" class="font_style"
                                                v-if="pathList[canvasIndex].textAlign!='1'" size="mini">居左</el-button>
                                            <el-button @click="editFontStyle(4,2)" class="font_style" type="success"
                                                v-if="pathList[canvasIndex].textAlign=='2'" size="mini">居中</el-button>
                                            <el-button @click="editFontStyle(4,2)" class="font_style"
                                                v-if="pathList[canvasIndex].textAlign!='2'" size="mini">居中</el-button>
                                            <el-button @click="editFontStyle(4,3)" class="font_style" type="success"
                                                v-if="pathList[canvasIndex].textAlign=='3'" size="mini">居右</el-button>
                                            <el-button @click="editFontStyle(4,3)" class="font_style"
                                                v-if="pathList[canvasIndex].textAlign!='3'" size="mini">居右</el-button>
  
                                        </div>
                                        <div style="height: 40px;">
                                            <el-button @click="editFontStyle(5)" class="font_style" type="success"
                                                v-if="pathList[canvasIndex].underline=='1'" size="mini">下划线</el-button>
                                            <el-button @click="editFontStyle(5)" class="font_style"
                                                v-if="pathList[canvasIndex].underline!='1'" size="mini">下滑线</el-button>
  
                                            <el-select size="mini" style="width: 90px;margin-left: 10px;"
                                                v-model="pathList[canvasIndex].family" placeholder="请选择" @change="updateCanvas()">
                                                <el-option v-for="item in familyEs" :key="item.value"
                                                    :label="item.label" :value="item.value">
                                                </el-option>
                                            </el-select>
  
                                        </div>
  
                                    </div>
  
                                </div>
                                <div style="height:35px;">
                                    <div class="property">
                                        坐标</div>
                                    <div class="property_div" >
                                        <div class="XYWH">
                                            <div> <input class="XYWH-input"
                                                    :class="keyDown==1?'identity-input':'identity-input2'"
                                                    v-on:keydown="keyup($event,XYWH.x,1)" @input="editXYWH(XYWH.x,1)"
                                                    v-model="XYWH.x" /></div>
                                            <div> x轴</div>
                                        </div>
                                        <div class="XYWH">
                                            <div> <input class="XYWH-input"
                                                    :class="keyDown==1?'identity-input':'identity-input2'"
                                                    v-on:keydown="keyup($event,XYWH.y,2)" @input="editXYWH(XYWH.y,2)"
                                                    v-model="XYWH.y" /></div>
                                            <div> y轴</div>
                                        </div>
                                        <label v-if="pathList[canvasIndex].type==3&&pathList[canvasIndex].module=='A'">
                                            <div class="XYWH">
                                                <div> <input class="XYWH-input"
                                                        :class="keyDown==1?'identity-input':'identity-input2'"
                                                        v-on:keydown="keyup($event,XYWH.r,5)"
                                                        @input="editXYWH(XYWH.r,5)" v-model="XYWH.r" /></div>
                                                <div>半径</div>
                                            </div>
                                        </label>
                                        <label v-else>
                                            <div class="XYWH">
                                                <div> <input class="XYWH-input"
                                                        :class="keyDown==1?'identity-input':'identity-input2'"
                                                        v-on:keydown="keyup($event,XYWH.w,3)"
                                                        @input="editXYWH(XYWH.w,3)" v-model="XYWH.w" /></div>
                                                <div> 宽</div>
                                            </div>
                                            <div
                                                v-if="pathList[canvasIndex].module=='B'&&(pathList[canvasIndex].type==1||pathList[canvasIndex]==2)">
                                            </div>
                                            <div v-else class="XYWH">
                                                <div>
                                                    <input class="XYWH-input"
                                                        :class="keyDown==1?'identity-input':'identity-input2'"
                                                        v-on:keydown="keyup($event,XYWH.h,4)"
                                                        @input="editXYWH(XYWH.h,4)" v-model="XYWH.h" />
                                                </div>
                                                <div> 高</div>
                                            </div>
                                        </label>
                                    </div>
  
                                </div>
                                <div>
                                    <el-button @click="removeCanvas()" size="medium"
                                        style="width:calc(100% - 20px); margin: 10px;" type="danger">
                                        删除元素</el-button>
  
  
                                </div>
                                <div>
  
                                    <el-button @click="copyCanvas()" size="medium"
                                        style="width:calc(100% - 20px); margin: 10px;" type="success">
                                        复制元素</el-button>
  
                                </div>
                            </label>
  
                        </el-tab-pane>
  
                    </el-tabs>
                </div>
            </div>
        </el-row>
  
  
    </div>
  
  </template>
  <script>
    import jQuery from "jquery";
    import "jquery-qrcode";
    import rulerDrag from "@/components/ruler/index.vue";
    import Rect from "@/components/graph/shape/rect";
    import { nModulesFromVersion, getVersion as getQRCodeVersion, toUtf8 } from "./js/qrCodeParam";
    import axios from "@/utils/request";
    const zipImg = require('@/assets/zip.png');
    import "./js/canvas2image";
import { message } from "ant-design-vue";

    export default {
        components: {
            rulerDrag
        },
        props: {
            params: {
                type: Object,
                default: () => ({})
            }
        },
        data() {
  
            // 条形图
            return {
                isZipUpload: false, // 是上传图片还是还穿zip，点击重新上传的时候会用到
                // 导入加载的图片
                iconListLoaded: {
                    save: require('./assets/baocun.png'),
                    lowestLevel: require('./assets/diceng.png'),
                    topestLevel: require('./assets/dingceng.png'),
                    back: require('./assets/fanhui.png'),
                    topAlign: require('./assets/jushangduiqi.png'),
                    leftAlign: require('./assets/zuoduiqi.png'),
                    rightAlign: require('./assets/youduiqi.png'),
                    bottomAlign: require('./assets/juxiaduiqi.png'),
                    centerAlign: require('./assets/juzhongduiqi.png'),
                    clear: require('./assets/qingkong.png'),
                    preview: require('./assets/yulan.png'),
                },
                familyEs: [
                    {
                        value: 'SourceHanSerifCN-VF',
                        label: '思源宋体'
                    },
                    {
                        value: 'Hiragino Sans GB',
                        label: '冬青黑体'
                    },
                    {
                        desc: 'AlibabaPuHuiTi-3',
                        value: 'AlibabaPuHuiTi-3-Bold',
                        label: '阿里普惠',
                        regular: 'AlibabaPuHuiTi-3-Regular',
                        bold: 'AlibabaPuHuiTi-3-Bold'
                    },
                ],
                imageBean: {},
                keyDown: 1,
                activeName: 'first',
                editCanvasBody: {
                    other: ""
                }, //属性名称
                //type动态2文字3图片4二维码5条形码
                dynamicList: [{
                        id: 1,
                        k: "name",
                        name: "商品名称",
                        type: 2,
  
                    }, {
                        id: 2,
                        k: "image",
                        name: "商品图片",
                        type: 3,
                    },
                    {
                        id: 3,
                        k: "qrCode",
                        name: "商品二维码",
                        type: 4,
                    },
                    {
                        id: 4,
                        k: "barCode",
                        name: "商品条形码",
                        type: 5,
                    },
                ],
                //**********************************上传图片系列*************************8
                fileUrl: '', //上传文件的域名地址
                limitNum: 1, //文件上传个数限制
                fileList: [], //文件列表
                showFileList: false, //文件列表是否显示,默认不显示
                //**********************************上传图片系列*************************
                imgNum: 0,
                url: '',
                srcList: [
  
                ],
                previewImg: false,
                selectSpot: [], //旋转元素点
                spot: -1,
                spotCopy: -1,
  
                canvasGridW: 10, //网格线宽度
                canvasGridH: 10, //网格线高度
                canvasGridC: 'lightgray', //网格线颜色
                ctx: null, //canvas
                canvasWidth: 800, //canvas宽
                canvasHeight: 272, //canvas高
                pathList: [], //canvas内容体
                canvasIndex: -1, //canvas元素下标
                canvasIndexCopy: -1,
                isDown: false, //鼠标是否按下
                mouse: {
                    x: 0, //鼠标按下x坐标
                    y: 0, //鼠标按下y坐标
                },
                activeNames: ['1'],
                basicControls: [{
                    type: 1,
                    name: "矩形",
  
                }], //基础控件
                imageDraw: false,
                XYWH: {
                    x: 0,
                    y: 0,
                    w: 0,
                    h: 0,
                    r: 0,
                },
                isUploadAgain: 1, //重新上传2:是
  
                batchSelectedCanvas: [],
                tempBatchSelectedCanvas: [],
                batchSelectedCanvasEditing: false,
                // 文字颜色和填充颜色
                colorList: [
                    { value: '#000000', label: '黑色' },
                    { value: '#ffffff', label: '白色' },
                    { value: '#C00000', label: '红色' },
                ],

                rulerLeftVal: 0,
                canvasLoading: true,
                rulerWidthSize: 0, // 刻度尺宽除以100之后的
                rulerHeightSize: 0, // 刻度尺高除以100之后的
                canvasIpt: {
                    w: 0,
                    h: 0,
                    t: 0,
                    l: 0
                },
                clickItem3times: 0,
                lastClickItemIdx: null,

                undoStock: [], // 撤销的栈，右边表单每blur一次，中间画布canvasIndex每切换一次就推一次
                crtUndoIndex: -1, // 当前到的是撤销的哪一步，默认是undoStock的长度，撤销时，crtUndoIndex也会相应变化
            }
        },
        watch: {
            canvasIndex(newVal, oldVal) {
                if (oldVal == -1) {
                    return;
                }
                let undoStockItem = this.undoStock[this.undoStock.length - 1];
                if (JSON.stringify(undoStockItem) === JSON.stringify(this.pathList)) {
                    return;
                }
                this.undoStock.push([
                    ...JSON.parse(JSON.stringify(this.pathList))
                ]);
                this.crtUndoIndex ++;
                if (this.crtUndoIndex > 0) {
                    this.undoStock = this.undoStock.slice(0, this.crtUndoIndex + 1);
                }
                if (this.undoStock.length >= 10) {
                    this.undoStock.shift();
                }
            }
        },
        methods: {
            async initGraphParams() {
                console.error("表单参数是", this.params);
                let data = {};
                try {
                    data = await axios({
                        url: `/template/file/${this.params.templateCode}`,
                        method: 'get',
                    });
                } catch (e) {

                }
                // 设置画布大小
                let { width = 800, height = 272, type = 1 } = this.params;
                this.canvasWidth = width;
                this.canvasHeight = height;
                this.rulerWidthSize = Math.ceil(this.canvasWidth / 100);
                this.rulerHeightSize = Math.ceil(this.canvasHeight / 100);
                type = + type;
                // // 设置底色和文字颜色, 0是黑白，1是黑白红， 2是黑白黄
                switch (type) {
                    case 1:
                        this.colorList = [
                            { value: '#000000', label: '黑色' },
                            { value: '#ffffff', label: '白色' },
                            { value: '#C00000', label: '红色' }
                        ]
                        break;
                    case 2:
                        this.colorList = [
                            { value: '#000000', label: '黑色' },
                            { value: '#ffffff', label: '白色' },
                            { value: '#FFC000', label: '黄色' }
                        ]
                        break;
                    default:
                        this.colorList = [
                            { value: '#000000', label: '黑色' },
                            { value: '#ffffff', label: '白色' },
                            { value: '#C00000', label: '红色' }
                        ]
                        break;
                }
                if (data.code != 200 ) {
                    this.$nextTick(() => {
                        this.draw();
                    })
                    return;
                }
                // this.pathList = data.data.screen_block.map(item => {
                //     if(item.valueType == 'text') {
                //         item.family = (item.family || '').slice(0, -4);
                //     }

                //     item.fromServer = true;
                //     return item;
                // });
                this.pathList = [];
                for(let i = 0; i < (data.data.screen_block || []).length; i ++) {
                    let item = data.data.screen_block[i];
                    if(item.valueType == 'text') {
                        item.family = (item.family || '').slice(0, -4);
                    }
                    if(item.fileId && !item.isZip) {
                        let fileResp = await axios({
                            url: `/template/assets/${item.fileId}`,
                            responseType: 'arraybuffer'
                        });
                        fileResp = `data:image/png;base64,${this.arrayBufferToBase64(fileResp)}`;
                        item.originPic = fileResp;
                        fileResp = await this.shakeFixedImage(fileResp, item.w, item.h, item.isShake)
                        item.content = fileResp;
                    }
                    if(item.fileId && item.isZip) {
                        item.originPic = zipImg;
                        item.content = zipImg;
                    }
                    item.fromServer = true;
                    this.pathList.push(item);
                }
                this.$nextTick(() => {
                    this.draw();
                })
            },
            handleKeyDown(e) {
                // 上下左右移动
                if ([37, 38, 39, 40, 87, 65, 83, 68].indexOf(e.keyCode) > -1) {
                    return this.handleKeyUpMove(e);
                }
            },
            handleKeyUpMove(e) {
                let map = {
                    37: [-2, 0],
                    38: [0, -2],
                    39: [2, 0],
                    40: [0, 2],
                    87: [0, -2],
                    65: [-2, 0],
                    83: [0, 2],
                    68: [2, 0]
                }
                if (this.canvasIndex > -1) {
                    this.pathList[this.canvasIndex].x += map[e.keyCode][0];
                    this.pathList[this.canvasIndex].y += map[e.keyCode][1];
                    return this.draw();
                }
                if (this.batchSelectedCanvas.length === 0) {
                    return;
                } 
                this.batchSelectedCanvas.forEach(c => {
                    c.x += map[e.keyCode][0];
                    c.y += map[e.keyCode][1];
                });
                this.draw();
                this.batchDrawSelectCanvas(this.pathList);
            },
            handleKeyUp(e) {
                // 删除
                if ( [8, 46].indexOf(e.keyCode) > -1 ) {
                    return this.handleKeyUpDel(e);
                }
            },
            handleKeyUpDel(e) {
                if (this.canvasIndex > -1) {
                    this.pathList.splice(this.canvasIndex, 1);
                    this.canvasIndex = -1;
                    return this.draw();
                }
                if (this.batchSelectedCanvas.length === 0) {
                    return;
                } 
                let selectedCanvasMap = {};
                this.batchSelectedCanvas.forEach(c => selectedCanvasMap[c.id] = true);
                this.pathList = this.pathList.filter(p => {
                    return !selectedCanvasMap[p.id]
                });
                this.batchSelectedCanvas = [];
                this.draw();
            },
            // // 计算左边ruler的left
            getRulerLeftVal() {
                let canvasEle = document.getElementById('canvas');
                setTimeout(() => {
                    this.rulerLeftVal = canvasEle.offsetLeft - 60 - 10;
                    this.canvasLoading = false;
                }, 1000);
            },
            // 清空选中
            clearSelect() {
                this.canvasIndex = -1;
                this.draw();
            },
            importData() {
                this.pathList =  
                    [
                        {"id":1,"type":1,"img":"","content":"我的位置","other":"矩形","x":28,"y":12,"w":100,"h":100,"index":0,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":0,"scale":1,"module":"A","underline":"2","removeLine":"2","valueType":""},
                        {"id":2,"type":2,"img":"","content":"我的位置","other":"圆角矩形","x":153,"y":10,"w":100,"h":100,"index":1,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":20,"scale":1,"module":"A","underline":"2","removeLine":"2","valueType":""},
                        {"id":3,"type":3,"img":"","content":"我的位置","other":"圆形","x":284,"y":8,"w":100,"h":100,"index":2,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":50,"scale":1,"module":"A","underline":"2","removeLine":"2","valueType":""},
                        {"id":4,"type":4,"img":"","content":"我的位置","other":"直线","x":0,"y":0,"w":1,"h":50,"index":3,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":0,"scale":1,"module":"A","underline":"2","removeLine":"2","valueType":""},
                        {"id":5,"type":5,"img":"","content":"我的位置","other":"二维码","x":411,"y":13,"w":100,"h":100,"index":4,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":50,"scale":1,"module":"A","underline":"2","removeLine":"2","valueType":""},
                        {"id":6,"type":6,"img":"","content":"123456789","other":"条形码","x":549,"y":16,"w":140,"h":80,"index":5,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":50,"scale":1,"module":"A","underline":"2","removeLine":"2","valueType":""},
                        {"id":7,"type":1,"img":"","content":"我的位置","other":"空文本","x":14,"y":124,"w":400,"h":24,"index":6,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":50,"scale":1,"module":"B","underline":"2","removeLine":"2","valueType":"text"},
                        {"id":8,"type":2,"img":"","content":999,"other":"数字","x":18,"y":156,"w":800,"h":24,"index":7,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":50,"scale":1,"module":"B","underline":"2","removeLine":"2","valueType":"number"},
                        {"id":9,"type":3,"img":"","content":"2023-11-10","other":"日期","x":17,"y":193,"w":800,"h":18,"index":8,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":50,"scale":1,"module":"B","underline":"2","removeLine":"2","valueType":"date"},
                        {"id":10,"type":4,"img":"","content":"16:09:19","other":"时间","x":23,"y":223,"w":800,"h":18,"index":9,"full":"1","color":"#000000","baseColor":"transparent","fontSize":18,"italic":"2","family":"SimSun","bold":"1","textAlign":"1","topAlign":"1","angle":0,"r":50,"scale":1,"module":"B","underline":"2","removeLine":"2","valueType":"time","tempContent":"2023-11-25T08:09:19.660Z"}
                    ];
                this.draw();
            },
            alignUp() {
                if(this.batchSelectedCanvas.length == 0) {
                    return;
                }
                let yAxisArr = this.batchSelectedCanvas.map(item => item.y);
                let yMin = Math.min(...yAxisArr);
                this.batchSelectedCanvas.forEach(item => item.y = yMin);
                this.draw();
            },
            alignDown() {
                if(this.batchSelectedCanvas.length == 0) {
                    return;
                }
                let yAxisArr = this.batchSelectedCanvas.map(item => item.y);
                let yMax = Math.max(...yAxisArr);
                this.batchSelectedCanvas.forEach(item => item.y = yMax);
                this.draw();
            },
            alignLeft() {
                if(this.batchSelectedCanvas.length == 0) {
                    return;
                }
                let xAxisArr = this.batchSelectedCanvas.map(item => item.x);
                let xMin = Math.min(...xAxisArr);
                this.batchSelectedCanvas.forEach(item => item.x = xMin);
                this.draw();
            },
            alignCenter() {
                if(this.batchSelectedCanvas.length == 0) {
                    return;
                }
                let xAva = 0, yAva = 0;
                this.batchSelectedCanvas.forEach(item => {
                    xAva += item.x
                    yAva += item.y;
                });
                xAva = xAva / this.batchSelectedCanvas.length;
                yAva = yAva / this.batchSelectedCanvas.length;
                this.batchSelectedCanvas.forEach(item => {
                    item.x = xAva;
                    item.y = yAva;
                });
                this.draw();
            },
            alignRight() {
                if(this.batchSelectedCanvas.length == 0) {
                    return;
                }
                let xAxisArr = this.batchSelectedCanvas.map(item => item.x);
                let xMax = Math.max(...xAxisArr);
                this.batchSelectedCanvas.forEach(item => item.x = xMax);
                this.draw();
            },
            levelUp() {
                if (this.canvasIndex < 0) {
                    return;
                }
                let indexArr = this.pathList.map(item => item.index);
                let level = Math.max(...indexArr) + 1;
                this.$set(this.pathList, this.canvasIndex, {
                    ...this.pathList[this.canvasIndex],
                    index: level
                });
                this.pathList.sort((a, b) => a.index - b.index);
                this.canvasIndex = this.pathList.length - 1;
                this.draw();

                this.batchDrawSelectCanvas(this.pathList);
            },
            levelDown() {
                if (this.canvasIndex < 0) {
                    return;
                }
                let indexArr = this.pathList.map(item => item.index);
                let level = Math.min(...indexArr) - 1;
                this.$set(this.pathList, this.canvasIndex, {
                    ...this.pathList[this.canvasIndex],
                    index: level
                });
                this.pathList.sort((a, b) => a.index - b.index);
                this.canvasIndex = 0;
                this.draw();
            },
            addText(v) {
                let bean = this.getCanvasBean()
                bean.type = v.type;
                bean.module = "B",
                    bean.h = bean.fontSize;
                bean.other = v.name;
                bean.content = v.k
                bean.w = this.canvasWidth
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            //重新上传
            uploadAgain() {
                this.isUploadAgain = 2;
                let doc = document.getElementById("uploadPic")
                // 判断是上传图片还是zip
                if (this.isZipUpload) {
                    doc = document.getElementById('uploadZip');
                }
                doc.click()
            },
            //保存canvas
            async saveCanvas() {
                let color = "black_white_red";
                if ( this.params.type == 0) {
                    color = "black_white";
                }
                if ( this.params.type == 2 ) {
                    color = "black_white_yellow"
                }
                let pathList = JSON.parse(JSON.stringify(this.pathList));
                pathList.forEach(item => {
                    if ( item.module == 'B' && item.valueType == 'text') {
                        item.family += '.ttf'
                        item.varName && (item.isVar = true);
                        !item.varName && (item.isVar = false);
                    }
                    delete item.fromServer;

                })
                let data = {
                    "background_color": "white",
                    "color": color,
                    "dataSource": "priSmart",
                    "direction": "0",
                    "height": this.canvasHeight,
                    "originDirection": 90,
                    "overlap_rule": "order_wise",
                    "size": this.params.screenSize,
                    "width": this.canvasWidth,
                    "screen_block": pathList.map(item => {
                        delete item.originPic;
                        delete item.content;
                        return item;
                    }),
                };
                await axios({
                    url: '/template/file/save',
                    method: 'post',
                    data: {
                        templateCode: this.params.templateCode,
                        json: JSON.stringify(data)
                    },
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
                    }
                });
                this.$message.success('保存为模板成功');
            },
            goBack() {
                this.$emit('close');
            },
            getProperty() {
                if (this.canvasIndex < 0) {
                    return "属性";
                } else {
                    let v = this.pathList[this.canvasIndex];
  
                    return "" + v.other + v.id;
                }
  
            },
            getCopyCanvasBean(v) {
                let id = this.pathList.length + 1;
                let bean = JSON.parse(JSON.stringify(v))
                bean.id = id
                bean.x = v.x + 10
                bean.y = v.y + 10
                return bean;
            },
            //复制元素
            copyCanvas() {
                if (this.canvasIndex < 0) return;
                let v = this.pathList[this.canvasIndex];
                if (v.imgDraw) {
                    let bean = this.getCopyCanvasBean(v)
                    bean.imgDraw = true;
                    let doc = document.getElementById("drawImg" + v.id)
                    this.canvasIndex = bean.id - 1;
                    this.imageBean = bean
                    this.pathList.push(bean)
                    this.canvasIndex = this.pathList.length - 1;
                    this.$nextTick(() => {
                        this.addImage(doc.src)
                    })
  
                } else {
                    let bean = this.getCopyCanvasBean(v)
  
                    this.canvasIndex = bean.id - 1;
                    this.pathList.push(bean);
                    this.canvasIndex = this.pathList.length - 1;
  
                    this.$nextTick(() => {
  
                        this.draw();
                    })
                }
  
  
            },
            //删除元素
            removeCanvas() {
  
                if (this.canvasIndex < 0) return;
                if (this.pathList.length <= 1) {
                    this.clearCanvas();
  
                } else {
                    this.pathList.splice(this.canvasIndex, 1);
                    this.canvasIndex = this.pathList.length - 1;
                    this.pathList.forEach((v, i) => {
  
                        if (i == 0) {
  
                            v.id = 1
  
                        } else {
                            v.id = i + 1
                        }
  
                    })
                    this.draw();
                }
  
  
            },
            gernerteId(index) {
                return "drawImg" + index
            },
            //修改字体样式
            editFontStyle(type, num) {
                let v = this.pathList[this.canvasIndex]
  
                switch (type) {
                    case 1:
                        // 如果有regular和bold就使用这两种字体，否则就使用默认的
                        let familyObj = this.familyEs.find(item => {
                            if (item.desc && v.family.indexOf(item.desc) > -1) {
                                return true;
                            }
                            return false;
                        });
                        let bold = v.bold;
                        if (bold == '1') {
                            v.bold = '2'
                            if (familyObj) {
                                v.family = familyObj.regular;
                                familyObj.value = familyObj.regular;
                            }
                        } else {
                            v.bold = '1';
                            if (familyObj) {
                                v.family = familyObj.bold;
                                familyObj.value = familyObj.bold;
                            }
                        }
                        break;
                    case 2:
                        let italic = v.italic;
                        if (italic == '1') v.italic = '2';
                        else v.italic = '1';
  
                        break;
                    case 3:
                        let removeLine = v.removeLine;
                        if (removeLine == '1') v.removeLine = '2';
                        else v.removeLine = '1';
  
                        break;
  
                    case 4:
                        let textAlign = v.textAlign;
                        v.textAlign = num + '';
  
                        break;
                    case 5:
                        let underline = v.underline;
                        if (underline == '1') v.underline = '2';
                        else v.underline = '1';
  
                        break;
                }
                this.draw()
            },
            updateCanvas(e, field) {
                this.pathList.forEach(p => {
                    p.whRatio = p.w / p.h;
                })
                let v = this.pathList[this.canvasIndex]
                if (v.module == 'A' && (v.type == 6) && field == 'content') {
                    let ee = e.replace(/\D/g, '');
                    v.content = ee
                } else if ( v.module == 'A' && (v.type == 7) && field == 'isShake' ) {
                    // 切换图片抖动
                    this.shakeImage();
                    return;
                }
                // 改了源代码
                // } else if (v.module == 'B' && (v.type == 1 || v.type == 2)) {
                //     v.h = v.fontSize
                // }
                else if (v.module == 'B'){
                    v.h = v.fontSize
                    if (v.valueType == 'date' && v.content instanceof Date) {
                        let year = v.content.getFullYear();
                        let month = v.content.getMonth() + 1;
                        let day = v.content.getDate();
                        v.content = `${year}-${month}-${day}`
                    } else if (v.valueType == 'time' && v.tempContent instanceof Date) {
                        let date = v.tempContent;
                        let hour = date.getHours();
                        hour = hour < 10 ? `0${hour}` : hour;
                        let minutes = date.getMinutes();
                        minutes = minutes < 10 ? `0${minutes}` : minutes;
                        let seconds = date.getSeconds();
                        seconds = seconds < 10 ? `0${seconds}` : seconds;
                        v.content = `${hour}:${minutes}:${seconds}`
                    }
                }
  
  
                this.draw()
            },
            onBaseColorChange(canvasidx) {
                let canvas = {
                    ...this.pathList[canvasidx],
                    color: '#ffffff'
                };
                this.$set(this.pathList, canvasidx, canvas);
                this.draw();
            },
            keyup(e, value, type) {
  
                let inputs = document.getElementsByClassName("XYWH-input")
                value = parseInt(value)
  
                if (e.keyCode == 39) {
                    if (type == 5) {
                        type = 3;
                    }
                    this.keyDown = 1;
                    for (var i = 0; i < inputs.length; i++) {
                        // 如果是最后一个，则焦点回到第一个
  
                        if (i == (inputs.length - 1)) {
  
                            inputs[0].focus();
                            break;
                        } else if ((type - 1) == i) {
                            inputs[i + 1].focus();
                            break;
                        }
                    }
  
                }
                if (e.keyCode == 37) {
                    if (type == 5) {
                        type = 3;
                    }
                    this.keyDown = 2;
                    for (var i = 0; i < inputs.length; i++) {
                        // 如果是最后一个，则焦点回到第一个
  
                        if (i == 0) {
                            inputs[inputs.length - 1].focus();
                        } else
                        if ((type - 1) == i) {
                            inputs[i - 1].focus();
                            break;
                        }
                    }
  
                }
  
  
                let v = this.pathList[this.canvasIndex]
                if (e.keyCode == 38) {
                    this.keyDown = 1;
                    switch (type) {
                        case 1:
  
                            this.XYWH.x = value + 1;
                            v.x = this.XYWH.x
                            break;
                        case 2:
  
                            this.XYWH.y = value + 1;
                            v.y = this.XYWH.y
                            break;
                        case 3:
  
                            this.XYWH.w = value + 1;
                            v.w = this.XYWH.w
                            break;
                        case 4:
  
                            this.XYWH.h = value + 1;
                            v.h = this.XYWH.h
                            break;
                        case 5:
  
                            this.XYWH.r = value + 1;
                            v.w = v.w + 2;
                            v.h = v.h + 2
                            v.r = this.XYWH.r
                            break;
                    }
                }
                if (e.keyCode == 40) {
                    this.keyDown = 2;
                    switch (type) {
                        case 1:
  
                            this.XYWH.x = value - 1;
                            v.x = this.XYWH.x
                            break;
                        case 2:
  
                            this.XYWH.y = value - 1;
                            v.y = this.XYWH.y
                            break;
                        case 3:
  
                            this.XYWH.w = value - 1;
                            v.w = this.XYWH.w
                            break;
                        case 4:
  
                            this.XYWH.h = value - 1;
                            v.h = this.XYWH.h
                            break;
                        case 5:
                            if (value < 10) {
  
                            } else {
                                this.XYWH.r = value - 1;
                                v.w = v.w - 2;
                                v.h = v.h - 2
                                v.r = this.XYWH.r
                                break;
                            }
  
                    }
                }
                this.draw()
  
            },
            editXYWH(e, type) {
                let ee = e.replace(/\D/g, '');
                let num = parseInt(ee)
                let v = this.pathList[this.canvasIndex]
                switch (type) {
                    case 1:
                        if (e == '') {
                            v.x = 0;
                            this.XYWH.x = 0;
                        } else v.x = num
                        break;
                    case 2:
                        if (e == '') {
                            v.y = 0;
                            this.XYWH.y = 0;
                        } else v.y = num
                        break;
                    case 3:
                        if (e == '') {
                            v.w = 0;
                            this.XYWH.w = 0;
                        } else v.w = num
                        break;
                    case 4:
                        if (e == '') {
                            v.h = 0;
                            this.XYWH.h = 0;
                        } else v.h = num
                        break;
                    case 5:
                        if (e == '' || e < 10) {
                            v.r = 10;
                            v.w = 2 * v.r;
                            v.h = 2 * v.r;
                            this.XYWH.r = 10;
                        } else {
                            v.h = 2 * num
                            v.w = 2 * num
                        }
                        break;
                }
  
                this.draw()
  
            },
            //绘制空文本
            drawEmptyText(v) {
                let ctx = this.ctx;
                ctx.beginPath()
  
                this.elementRotation(ctx, v)
                this.scale(ctx, v)
                ctx.fillStyle = v.color;

                ctx.moveTo(v.x, v.y);
                ctx.lineTo(v.x, v.y + v.h);
                ctx.lineTo(v.x + v.w, v.y + v.h);
                ctx.lineTo(v.x + v.w, v.y);
                ctx.closePath(); //使用closePath()闭合图形
                ctx.fillStyle = v.baseColor; 
                ctx.fill(); //确定填充

                ctx.beginPath();
                ctx.fillStyle = v.color;
                //文字粗细
  
                let bold = "bold";
                let italic = "italic";
                if (v.bold == '1') bold = "bold";
                else bold = "";
                if (v.italic == '1') italic = "italic";
                else italic = "";
                //文字粗细
                ctx.font = italic + " " + bold + " " + v.fontSize + 'px' + " " + v.family
                let x = v.x;
                let y = v.y;
                //文字左右居中
                let txt = v.content
                let textW = ctx.measureText(txt).width
                if (v.textAlign == '1') {
                    ctx.fillText(v.content, x, y + v.fontSize)
                    if (v.removeLine == '1') {
                        ctx.moveTo(v.x, v.y + v.fontSize / 2 + 5)
                        ctx.lineTo(v.x + textW, v.y + v.fontSize / 2 + 5)
                    }
                    if (v.underline == '1') {
                        ctx.moveTo(v.x, v.y + v.fontSize)
                        ctx.lineTo(v.x + textW, v.y + v.fontSize)
                    }
                }
                if (v.textAlign == '2') {
                    ctx.fillText(v.content, x + (v.w - textW) / 2, y + v.fontSize)
                    if (v.removeLine == '1') {
                        ctx.moveTo(x + (v.w - textW) / 2, v.y + v.fontSize / 2 + 5)
                        ctx.lineTo(x + (v.w - textW) / 2 + textW, v.y + v.fontSize / 2 + 5)
                    }
                    if (v.underline == '1') {
                        ctx.moveTo(x + (v.w - textW) / 2, v.y + v.fontSize)
                        ctx.lineTo(x + (v.w - textW) / 2 + textW, v.y + v.fontSize)
                    }
                }
                if (v.textAlign == '3') {
                    ctx.fillText(v.content, x + v.w - textW, y + v.fontSize)
                    if (v.removeLine == '1') {
                        ctx.moveTo(x + v.w - textW, v.y + v.fontSize / 2 + 5)
                        ctx.lineTo(x + v.w, v.y + v.fontSize / 2 + 5)
                    }
                    if (v.underline == '1') {
                        ctx.moveTo(x + v.w - textW, v.y + v.fontSize)
                        ctx.lineTo(x + v.w, v.y + v.fontSize)
                    }
                }
                ctx.lineWidth = 2;
                ctx.strokeStyle = v.color;
                ctx.stroke()
                ctx.closePath()
                ctx.restore()
  
            },
            // 添加文本
            addEmptyText() {
                let bean = this.getCanvasBean()
                bean.type = 1;
                bean.module = "B",
                    bean.h = bean.fontSize;
                bean.other = "空文本";
  
                bean.w = this.canvasWidth / 2
                bean.valueType = 'text'; //值为文本类型
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            // 添加数字
            addEmptyNumber() {
                let bean = this.getCanvasBean()
                bean.type = 2;
                bean.module = "B",
                    bean.h = bean.fontSize;
                bean.other = "数字";
                bean.content = "0";
                bean.w = this.canvasWidth
                bean.valueType = 'number'; //值为数字类型
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            // 添加日期
            addEmptyDate() {
                let bean = this.getCanvasBean()
                bean.type = 3;
                bean.module = "B",
                    bean.h = bean.fontSize;
                bean.other = "日期";
                let date = new Date();
                let year = date.getFullYear();
                let month = date.getMonth() + 1;
                month = month < 10 ? `0${month}` : month;
                let day = date.getDate();
                day = day < 10 ? `0${day}` : day;
                bean.content = `${year}-${month}-${day}`
                bean.w = this.canvasWidth
                bean.valueType = 'date'; //值为数字类型
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            // 添加时间
            addEmptyTime() {
                let bean = this.getCanvasBean()
                bean.type = 4;
                bean.module = "B",
                    bean.h = bean.fontSize;
                bean.other = "时间";
                let date = new Date();
                let hour = date.getHours();
                hour = hour < 10 ? `0${hour}` : hour;
                let minutes = date.getMinutes();
                minutes = minutes < 10 ? `0${minutes}` : minutes;
                let seconds = date.getSeconds();
                seconds = seconds < 10 ? `0${seconds}` : seconds;
                bean.tempContent = new Date();
                bean.content = `${hour}:${minutes}:${seconds}`
                bean.w = this.canvasWidth
                bean.valueType = 'time'; //值为数字类型
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            beforeUpload(file) {
  
                this.fileList = [];
                if (this.isUploadAgain == 1) {
                    let bean = this.getCanvasBean()
                    bean.type = 7;
                    bean.imgDraw = true
                    bean.other = "上传图片"
                    this.imageBean = bean
                    this.pathList.push(bean)
                    this.canvasIndex = this.pathList.length - 1;
                }
  
            },
  
  
            //文件上传成功时的钩子
            onSuccess(response, file, fileList) {
  
            },
            arrayBufferToBase64(buffer) {
                var binary = '';
                var bytes = new Uint8Array(buffer);
                var len = bytes.byteLength;
                for (var i = 0; i < len; i++) {
                    binary += String.fromCharCode(bytes[i]);
                }
                // 对二进制字符串进行base64编码
                return window.btoa(binary);
            },
            // base64图片转file的方法（base64图片, 设置生成file的文件名）
            base64ToFile(base64, fileName) {
                // 将base64按照 , 进行分割 将前缀  与后续内容分隔开
                let data = base64.split(',');
                // 利用正则表达式 从前缀中获取图片的类型信息（image/png、image/jpeg、image/webp等）
                let type = data[0].match(/:(.*?);/)[1];
                // 从图片的类型信息中 获取具体的文件格式后缀（png、jpeg、webp）
                let suffix = type.split('/')[1];
                // 使用atob()对base64数据进行解码  结果是一个文件数据流 以字符串的格式输出
                const bstr = window.atob(data[1]);
                // 获取解码结果字符串的长度
                let n = bstr.length
                // 根据解码结果字符串的长度创建一个等长的整形数字数组
                // 但在创建时 所有元素初始值都为 0
                const u8arr = new Uint8Array(n)
                // 将整形数组的每个元素填充为解码结果字符串对应位置字符的UTF-16 编码单元
                while (n--) {
                    // charCodeAt()：获取给定索引处字符对应的 UTF-16 代码单元
                    u8arr[n] = bstr.charCodeAt(n)
                }
                // 利用构造函数创建File文件对象
                // new File(bits, name, options)
                const file =  new File([u8arr], `${fileName}.${suffix}`, {
                    type: type
                })
                // 将File文件对象返回给方法的调用者
                return file;
            },
            // 抖动特定图片(传base64，图片宽，图片高返回抖动后的base64)
            async shakeFixedImage(base64, picW, picH, isShake) {
                return new Promise(resolve => {
                    let img = new Image();
                    img.src = base64;
                    img.onload = () => {
                        // 将图片放置在uploadCanvas上并且变色
                        let uploadCanvas = document.getElementById('uploadCanvas');
                        uploadCanvas.width = picW;
                        uploadCanvas.height = picH;
                        let uploadCtx = uploadCanvas.getContext('2d');
                        uploadCtx.drawImage(img, 0, 0);
                        let uploadImageData = uploadCtx.getImageData(0,0,uploadCanvas.width, uploadCanvas.height);
                        // 图片数据进行抖动
                        if (isShake) {
                            this.ditheringBurke(uploadImageData);
                        }
                        let colorPalette = [
                            [0, 0, 0],
                            [255, 255, 255],
                            // [192, 0, 0], // #C00000
                            // [255, 192, 0], //FFC000
                        ];
                        if (this.params.type == 1) {
                            colorPalette.push([192, 0, 0]);
                        }
                        if (this.params.type == 2) {
                            colorPalette.push([255, 192, 0]);
                        }
                        for (var i = 0; i < uploadImageData.data.length; i += 4) {
                            let currentColor = [uploadImageData.data[i], uploadImageData.data[i + 1], uploadImageData.data[i + 2 ]];
                            let closestColor = this.getClosestColor(currentColor, colorPalette);
                            uploadImageData.data[i] = closestColor[0];
                            uploadImageData.data[i + 1] = closestColor[1];
                            uploadImageData.data[i + 2] = closestColor[2];
                        }
                        uploadCtx.putImageData(uploadImageData, 0, 0);
                        resolve(uploadCanvas.toDataURL("image/png", 1));
                    }
                })
            },
            // 抖动当前图片
            shakeImage() {
                let bean = this.pathList[this.canvasIndex];
                let img = new Image();
                img.src = bean.originPic;
                console.error('bean的originPic', bean.originPic);
                img.onload = () => {
                    // 将图片放置在uploadCanvas上并且变色
                    let uploadCanvas = document.getElementById('uploadCanvas');
                    uploadCanvas.width = bean.w;
                    uploadCanvas.height = bean.h;
                    let uploadCtx = uploadCanvas.getContext('2d');
                    uploadCtx.drawImage(img, 0, 0);
                    let uploadImageData = uploadCtx.getImageData(0,0,uploadCanvas.width, uploadCanvas.height);
                    // 图片数据进行抖动
                    if (bean.isShake) {
                        this.ditheringBurke(uploadImageData);
                    }
                    let colorPalette = [
                        [0, 0, 0],
                        [255, 255, 255],
                        // [192, 0, 0], // #C00000
                        // [255, 192, 0], //FFC000
                    ];
                    if (this.params.type == 1) {
                        colorPalette.push([192, 0, 0]);
                    }
                    if (this.params.type == 2) {
                        colorPalette.push([255, 192, 0]);
                    }
                    for (var i = 0; i < uploadImageData.data.length; i += 4) {
                        let currentColor = [uploadImageData.data[i], uploadImageData.data[i + 1], uploadImageData.data[i + 2 ]];
                        let closestColor = this.getClosestColor(currentColor, colorPalette);
                        uploadImageData.data[i] = closestColor[0];
                        uploadImageData.data[i + 1] = closestColor[1];
                        uploadImageData.data[i + 2] = closestColor[2];
                    }
                    uploadCtx.putImageData(uploadImageData, 0, 0);
                    let finalImg = uploadCanvas.toDataURL("image/png", 1);
                    bean.content = finalImg;
                    bean.fromServer = true;
                    this.draw();
                }
            },
            // 上传时的添加图片到canvas
            // isZip为0时， image是图片可以直接使用的src地址
            // isZip为1时， image是文件对象
            async addImage(image, isZip) {
                let bean = null;
                if (this.isUploadAgain == 1) {
                    bean = this.imageBean
  
                } else {
                    bean = this.pathList[this.canvasIndex]
  
                }

                // 如果是上传zip就先上传，以获取文件内容
                if (isZip == 1) {
                    let formData = new FormData();
                    formData.append('file', image);
                    formData.append('isJson', 0);
                    formData.append('isZip', 1);
                    formData.append('templateCode', this.params.templateCode);
                    let data = await axios({
                        url: `/template/file/upload`,
                        method: "post",
                        data: formData
                    });
                    bean.fileId = data.data.id;
                    bean.fromServer = true;
                    bean.content = zipImg;
                    bean.originPic = zipImg;
                    // 上传后根据文件id获取文件
                    image = zipImg;
                    bean.isShake = false;
                    bean.isZip = true;
                    bean.width = 168;
                    bean.height = 142;
                }

                // if (!bean.originPic) {
                //     console.error();
                //     this.$set(bean, 'originPic', image); //记录原图，方便切换
                // }
                this.$nextTick(async () => {
                    let doc = document.getElementById("drawImg" + bean.id)
                    if (!doc) {
                        doc = document.createElement('img');
                        doc.id = "drawImg" + bean.id;
                    }
                    doc.src = image;

                    let img = new Image();
                    img.src = image;

                    // // // 上传图片，保存文件id
                    // let file = this.base64ToFile(image, `img${Math.random().toString().slice(2)}`);
                    // let formData = new FormData();
                    // formData.append('file', file);
                    // formData.append('isJson', 0);
                    // formData.append('templateCode', this.params.templateCode);
                    // let data = await axios({
                    //     url: `/template/file/upload`,
                    //     method: "post",
                    //     data: formData
                    // });
                    // bean.fileId = data.data.id;
                    
                    img.onload = async () => {
                        // console.error("图片元素111", doc, doc.clientHeight, doc.clientWidth, doc.getBoundingClientRect());
                        if (isZip == 0) {
                            bean.w = doc.clientWidth;
                            bean.h =  doc.clientHeight;
                        }
                        bean.whRatio = bean.w / bean.h;
                        
                        // 将图片放置在uploadCanvas上并且变色
                        let uploadCanvas = document.getElementById('uploadCanvas');
                        uploadCanvas.width = bean.w || this.pathList[this.canvasIndex].w;
                        uploadCanvas.height = bean.h || this.pathList[this.canvasIndex].h;
                        console.error('bean', bean.isShake, this.pathList[this.canvasIndex].isShake);
                        let uploadCtx = uploadCanvas.getContext('2d');
                        uploadCtx.drawImage(img, 0, 0);
                        let uploadImageData = uploadCtx.getImageData(0,0,uploadCanvas.width, uploadCanvas.height);
                        // 图片数据进行抖动
                        if (bean.isShake || this.pathList[this.canvasIndex].isShake) {
                            this.ditheringBurke(uploadImageData);
                        }
                        if (isZip == 0) {
                            let colorPalette = [
                                [0, 0, 0],
                                [255, 255, 255],
                                // [192, 0, 0], // #C00000
                                // [255, 192, 0], //FFC000
                            ];
                            if (this.params.type == 1) {
                                colorPalette.push([192, 0, 0]);
                            }
                            if (this.params.type == 2) {
                                colorPalette.push([255, 192, 0]);
                            }
                            for (var i = 0; i < uploadImageData.data.length; i += 4) {
                                let currentColor = [uploadImageData.data[i], uploadImageData.data[i + 1], uploadImageData.data[i + 2 ]];
                                let closestColor = this.getClosestColor(currentColor, colorPalette);
                                uploadImageData.data[i] = closestColor[0];
                                uploadImageData.data[i + 1] = closestColor[1];
                                uploadImageData.data[i + 2] = closestColor[2];
                            }
                            uploadCtx.putImageData(uploadImageData, 0, 0);
                            let finalImg = uploadCanvas.toDataURL("image/png", 1);
                            // // // 上传图片，保存文件id
                            console.error('上传时的src', img.src);
                            let file = this.base64ToFile(img.src, `img${Math.random().toString().slice(2)}`);
                            let formData = new FormData();
                            formData.append('file', file);
                            formData.append('isJson', 0);
                            formData.append('isZip', isZip);
                            formData.append('templateCode', this.params.templateCode);
                            let data = await axios({
                                url: `/template/file/upload`,
                                method: "post",
                                data: formData
                            });
                            bean.fileId = data.data.id;
                            bean.content = finalImg;
                            bean.fromServer = true;
                            bean.originPic = img.src;
                        }
                        this.draw()
                    }
                    this.$nextTick(() => {
                        this.draw()
                    })
                })
                this.isUploadAgain = 1;
            },
            // 定义Burke抖动算法
            ditheringBurke(imageData) {
                var width = imageData.width;
                var height = imageData.height;
                var data = imageData.data;
                // 定义抖动矩阵
                var matrix = [
                    [0, 0, 0, 8, 4],
                    [2, 4, 8, 4, 2],
                    [1, 2, 4, 2, 1]
                ];
                // 遍历图像像素
                for (var y = 0; y < height; y++) {
                    for (var x = 0; x < width; x++) {
                    var index = (y * width + x) * 4;
                    var oldR = data[index];
                    var oldG = data[index + 1];
                    var oldB = data[index + 2];
                    var newR = oldR > 127 ? 255 : 0;
                    var newG = oldG > 127 ? 255 : 0;
                    var newB = oldB > 127 ? 255 : 0;
                    var errR = oldR - newR;
                    var errG = oldG - newG;
                    var errB = oldB - newB;
                    // 更新当前像素
                    data[index] = newR;
                    data[index + 1] = newG;
                    data[index + 2] = newB;
                    // 传播误差到相邻像素
                    for (var i = 0; i < matrix.length; i++) {
                        for (var j = 0; j < matrix[i].length; j++) {
                        var offsetX = j - Math.floor(matrix[i].length / 2);
                        var offsetY = i;
                        var neighborX = x + offsetX;
                        var neighborY = y + offsetY;
                        if (neighborX >= 0 && neighborX < width && neighborY >= 0 && neighborY < height) {
                                var neighborIndex = (neighborY * width + neighborX) * 4;
                                data[neighborIndex] += errR * matrix[i][j] / 32;
                                data[neighborIndex + 1] += errG * matrix[i][j] / 32;
                                data[neighborIndex + 2] += errB * matrix[i][j] / 32;
                            }
                        }
                    }
                  }
               }
               return imageData;
            },
            // 获取最接近的颜色
            // let currentColor = [125, 100, 50]; // 当前颜色的 RGB 值
            // let colorPalette = [
            //     [255, 0, 0], // 红色
            //     [0, 255, 0], // 绿色
            //     [0, 0, 255], // 蓝色
            //     [255, 255, 0], // 黄色
            //     [0, 255, 255] // 青色
            // ];
            getClosestColor(currentColor, colorPalette) {
                let closestColor = null;
                let minDistance = Number.MAX_VALUE;

                for (let color of colorPalette) {
                    let distance = Math.sqrt(
                        Math.pow(color[0] - currentColor[0], 2) +
                        Math.pow(color[1] - currentColor[1], 2) +
                        Math.pow(color[2] - currentColor[2], 2)
                    );

                    if (distance < minDistance) {
                        minDistance = distance;
                        closestColor = color;
                    }
                }

                return closestColor;
            },
            // 第二个参数是是否按照图片的真实大小来展示，
            drawImage(v, flag) {
                let ctx = this.ctx;
                this.elementRotation(ctx, v)
                this.scale(ctx, v)
                let image = document.getElementById("drawImg" + v.id)
                image.setAttribute('crossOrigin', 'anonymous');
                if (v.content  && v.fromServer) {
                    image.src = v.content;
                }
                image.onload = () => {
                    // 暂时关闭按图片大小展示图片
                    // if (flag) {
                    //     v.w = image.clientWidth;
                    //     v.h = image.clientHeight;
                    //     v.whRatio = v.w / v.h;
                    // }
                    ctx.drawImage(image, v.x, v.y, v.w, v.h);
                    // ctx.restore()
                    this.draw();
                    v.fromServer = false;
                }
                ctx.drawImage(image, v.x, v.y, v.w, v.h)
                ctx.restore()
  
  
            },
            //覆盖默认的上传行为,可以自定义上传的实现
            uploadFile(item) {
  
                let data = new FormData();
                data.append('file', item.file);
                this.isZipUpload = false;
                let that = this;
                 var reader = new FileReader();
                 reader.readAsDataURL(item.file);
  
                 reader.onload = function() {
                    // 0是上传图片
                     that.addImage(reader.result, 0);
  
                 }
    //              let url = "/upload/upload";
    //             this.$http.postJson(url, data).then(res => {
    //                 let result = res.data;
    //                 that.addImage(result.image)
  
    //             })
  
            },
            // 上传随机图(zip)
            uploadZip(item) {
                let data = new FormData();
                this.isZipUpload = true;
                data.append('file', item.file);
                // 1是上传zip
                this.addImage(item.file, 1)
                // let that = this;
                // var reader = new FileReader();
                // reader.readAsDataURL(item.file);
                // reader.onload = function() {
                //     // 1是上传zip
                //     that.addImage(reader.result, 1)
                // }
            },
            async uploadJSON(item) {
                this.canvasIndex = -1;
                let data = new FormData();
                data.append('file', item.file);
                data.append('templateCode', this.params.templateCode)
                data.append('isJson', 1);
                data.append('isZip', 0);
                let uploadResp = await axios({
                    url: `/template/file/upload`,
                    method: "post",
                    data
                });
                let fileResp = await axios({
                    url: `/template/assets/${uploadResp.data.id}`,
                    responseType: 'json'
                });
                if (fileResp.width != this.canvasWidth || fileResp.height != this.canvasHeight) {
                    return this.$message.error('导入json失败,宽高数据不匹配');
                }
                this.$message.success('导入json成功');
                this.pathList = [];
                for(let i = 0; i < (fileResp.screen_block || []).length; i ++) {
                    let item = fileResp.screen_block[i];
                    if(item.valueType == 'text') {
                        item.family = (item.family || '').slice(0, -4);
                    }
                    if(item.fileId && !item.isZip) {
                        let fileResp = await axios({
                            url: `/template/assets/${item.fileId}`,
                            responseType: 'arraybuffer'
                        });
                        fileResp = `data:image/png;base64,${this.arrayBufferToBase64(fileResp)}`;
                        item.originPic = fileResp;
                        fileResp = await this.shakeFixedImage(fileResp, item.w, item.h, item.isShake)
                        item.content = fileResp;
                    }
                    if(item.fileId && item.isZip) {
                        item.originPic = zipImg;
                        item.content = zipImg;
                    }
                    item.fromServer = true;
                    this.pathList.push(item);
                    console.warn('this.pathList', this.pathList);
                }
                this.$nextTick(() => {
                    this.draw();
                })
            },
            getQrcodeUrl() {
                let data =
                    "";
                return data
            },
            getBarcodeUrl() {
                let data =
                    ""
                return data;
            },
            getTextUrl() {
                return require("@/assets/text.png");
            }, 
            getNumberUrl() {
                return require("@/assets/number.png");
            },
            getDateUrl() {
                return require("@/assets/date.png");
            },
            getTimeUrl() {
                return require("@/assets/time.png");
            },
            getQrcodeImage() {
                let data =
                    ""
                return data;
            },
            getBarCode() {
                var canvas = document.createElement("canvas");
                canvas.width = 140;
                canvas.height = 80;
                var ctx = canvas.getContext('2d');
                ctx.beginPath()
                ctx.fillStyle = "#ffffff"
                ctx.rect(0, 0, 140, 80)
                ctx.fill()
                ctx.closePath()
                for (let i = 0; i < 20; i++) {
                    if (i == 8 || i == 3 || i == 13 || i == 17 || i == 16 || i == 9 || i == 19) {
                        ctx.beginPath()
                        ctx.lineWidth = 3
                        ctx.rect(13 + i * 6, 15, 1, 40)
                        ctx.stroke()
                        ctx.closePath()
                    } else {
                        ctx.beginPath()
                        ctx.lineWidth = 1
                        ctx.rect(13 + i * 6, 15, 1, 40)
                        ctx.stroke()
                        ctx.closePath()
                    }
  
                }
                ctx.beginPath()
                ctx.fillStyle = "#101010"
                ctx.font = "bold 16px 微软雅黑"
                ctx.fillText("123456789", 25, 70)
                ctx.stroke()
                ctx.closePath()
  
                let quality = 1
                let data = ""
                var dataURL = canvas.toDataURL("image/png", quality); //使用toDataUrl将图片转换成jpeg的格式,不要把图片压
                return dataURL;
            },
  
  
            //画布预览
            preview() {
                this.srcList = []
                this.previewImg = true;
                this.draw()
  
                let dc = document.getElementById("canvas")
                var tempSrc = dc.toDataURL("image/png");
  
                this.url = tempSrc
  
                this.srcList.push(tempSrc)
                let that = this;
                this.$nextTick(() => {
                    that.$refs.previewUrl.clickHandler()
  
                    that.previewImg = false;
  
                    that.draw()
                })
  
  
            },
            handleChange(val) {
  
            },
            //添加矩形
            addRect() {
                let v = this.getCanvasBean();
                v.r = 0;
  
                v.other = "矩形"
                this.pathList.push(v);
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            //添加圆角矩形
            addRoundRect() {
                let v = this.getCanvasBean()
                v.type = 2;
                v.other = "圆角矩形"
                v.r = 20;
                this.pathList.push(v)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            addBarCode() {
                let bean = this.getCanvasBean()
                bean.type = 6;
                bean.content = "123456789"
                bean.other = "条形码"
                bean.w = 140
                bean.h = 80
                bean.whRatio = bean.w / bean.h;
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            addQrCode() {
                let bean = this.getCanvasBean()
                bean.type = 5;
                bean.other = "二维码"
                bean.moduleSize = 5;
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            //添加直线
            addLine() {
                let bean = this.getCanvasBean()
                bean.type = 4;
                bean.other = "直线"
                bean.slope = "-1";  
                // bean.r = 0;
                // bean.w = 2;
                // bean.h = 50;
                // bean.color = '#ffffff';
                bean.full = '0';
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            //添加圆形
            addArc() {
                let bean = this.getCanvasBean()
                bean.other = "圆形"
                bean.type = 3;
                bean.r = 50;
                this.pathList.push(bean)
                this.canvasIndex = this.pathList.length - 1;
                this.draw()
            },
            //创建圆角矩形
            createRoundRect(ctx, w, h, r, x, y, v = {}) {
  
                ctx.beginPath();
                ctx.lineWidth = v.lineWidth || 1;
                ctx.moveTo(x + r, y);
                ctx.arcTo(x + w, y, x + w, y + h, r);
                ctx.arcTo(x + w, y + h, x, y + h, r);
                ctx.arcTo(x, y + h, x, y, r);
                ctx.arcTo(x, y, x + w, y, r);
                ctx.stroke()
                ctx.closePath()
            },
  
            scale(ctx, v) {
  
                let x = v.x + .5 * v.w
                let y = v.y + .5 * v.h
                ctx.translate(x, y)
  
                ctx.scale(v.scale, v.scale)
  
                ctx.translate(-x, -y)
  
            },
            getSelectSpot(e) {
  
                if (this.canvasIndex < 0) return;
  
                let ctx = this.ctx;
  
                let {
                    offsetX,
                    offsetY
                } = e;
  
                let index = -1
                let arrList = this.selectSpot;
                let vv = this.pathList[this.canvasIndex]
                ctx.beginPath()
                this.elementRotation(ctx, vv)
  
                for (let i = 0; i < arrList.length; i++) {
  
                    let v = arrList[i]
                    // ctx.fillStyle = "#063cff"
                    // ctx.strokeStyle = "#063cff"
                    ctx.fillStyle = "#FFFFFF"
                    ctx.strokeStyle = "#0000FF"
                    if (vv.module == "B") {
                        if (i == 1 || i == 4) {
                            ctx.rect(v.x, v.y, v.w, v.h)
                            ctx.fillRect(v.x, v.y, v.w, v.h)
                            ctx.stroke()
                        }
                    } else {
                        // if (vv.module == "A"&&vv.type==4) {
                        //     if (i == 6 || i == 7) {
                        //         ctx.rect(v.x, v.y, v.w, v.h)
                        //         ctx.fillRect(v.x, v.y, v.w, v.h)
                        //         ctx.stroke()
                        //     }
                        // }else{
                        //     ctx.rect(v.x, v.y, v.w, v.h)
                        //     ctx.fillRect(v.x, v.y, v.w, v.h)
                        //     ctx.stroke()
                        // }
                        ctx.rect(v.x, v.y, v.w, v.h)
                        ctx.fillRect(v.x, v.y, v.w, v.h)
                        ctx.stroke()
                    }
  
                    if (ctx.isPointInPath(offsetX, offsetY)) {
                        index = i
                        break;
                    }
                }
  
                if (index > -1 && index < 9) {
                    canvas.style.cursor = "col-resize";
                } else {
                    index = -1;
                    canvas.style.cursor = "default";
                }
  
                ctx.restore()
                if (index < 0) {
                    this.spot = index;
                } else {
                    this.spot = index;
                }
  
                this.spotCopy = index;
  
                return index;
  
            },
            //绘制圆角矩形
            drawRoundRect(v) {
                let ctx = this.ctx;
                if (2 * v.r > v.w || 2 * v.r > v.h) {
                    let bean = this.editCanvasBody;
                    v.r = bean.r;
                    v.w = bean.w;
                    v.h = bean.h;
                }
                if (v.type == 3) {
                    if (v.r < 15) v.r = 15;
                    v.w = 2 * v.r;
                    v.h = 2 * v.r;
                }
                // if(v.type==4){
                //     v.w= 20;
                // }
                ctx.strokeStyle = v.color
                //this.elementRotation(ctx, v)
                //this.scale(ctx, v)
                switch (v.type) {
                    case 4:
                        ctx.beginPath()
                        // if(v.type==4)ctx.lineWidth = 1;
                        // else ctx.lineWidth = 2;
                        ctx.lineWidth = v.lineWidth || 1;
                        ctx.strokeStyle = 'transparent';
                        ctx.rect(v.x, v.y, v.w, v.h);
                        ctx.stroke();
                        ctx.closePath();
                        ctx.beginPath();
                        ctx.strokeStyle = v.color || '#000000';
                        if (v.slope == -1) {
                            // 绘制反斜线
                            ctx.moveTo(v.x, v.y);
                            ctx.lineTo(v.x + v.w, v.y + v.h);
                        } else if (v.slope == 0) {
                            ctx.moveTo(v.x, v.y + Math.floor(v.h / 2));
                            ctx.lineTo(v.x + v.w, v.y + Math.floor(v.h / 2));
                        } else if (v.slope == 1) {
                            ctx.moveTo(v.x, v.y + v.h);
                            ctx.lineTo(v.x + v.w, v.y);
                        }
                        ctx.stroke()
                        ctx.closePath()
                        break;
                    default:
                        this.createRoundRect(ctx, v.w, v.h, v.r, v.x, v.y, v)
                        break;
                }
  
  
                if (v.full == '1') {
                    ctx.fillStyle = v.color
                    ctx.fill()
                } else {
  
                    ctx.stroke()
                }
                ctx.restore()
            },
  
            //canvasBean实体类
            getCanvasBean() {
                let id = 0;
                let length = this.pathList.length;
                if (this.pathList.length == 0) id = 1;
                else id = length + 1
                let bean = {
                    id: id,
                    type: 1,
                    img: "",
                    content: '我的位置',
                    other: '',
                    x: 0,
                    y: 0,
                    w: 100,
                    h: 100,
                    whRatio: 1,
                    index: 0, // 层级，只决定了谁在上谁在下，用于整理排序后的数组
                    full: '1', //填充1是 2否
                    lineWidth: '1',
                    color: "#000000", //字体颜色
                    baseColor: "transparent", //底色，module为B的时候生效
                    fontSize: 18,
                    italic: "2", //斜体1:是2否
                    family: "SourceHanSerifCN-VF",
                    bold: "1", //1加重2否
                    textAlign: '1', //1左,2中,3右
                    topAlign: '1', //1上2，中,3右
                    angle: 0, //角度
                    r: 50, //半径
                    scale: 1, //缩放比例
                    module: 'A',
                    underline: '2', //下划线
                    removeLine: '2', //删除线1是2否
                    valueType: '', //值的类型，内容是字符串还是数字还是时间等等， 取值 text:文本类型  number:数字类型  date: 日期类型  time:时间类型 
                }
                // 创建bean的时候，就将index值设置为pathList中最大的那个加一，让他在上面
                let indexArr = this.pathList.map(item => item.index);
                if (indexArr.length === 0) {
                    bean.index = 0;
                } else {
                    bean.index = Math.max(...indexArr) + 1;
                }
                return bean;
            },
            //鼠标滚轮事件
            mousewheel(e) {
                if (this.canvasIndex < 0 && !this.isDown) return;
                let {
                    deltaY
                } = e;
                if (deltaY > 0) this.minScale()
                else this.maxScale();
  
            },
            //鼠标抬起
            mouseup(e) {
                this.preventDefault(e)
                this.spotCopy = -1;
                let v = this.pathList[this.canvasIndex]
                
  
                // if (this.canvasIndex > -1) {
                //     if (v.module == 'A' && v.type == 4) {
  
                //         v.w = 2;
                //         v.full = '1'
  
                //     }
                // }

                this.isDown = false
                this.canvasIndexCopy = -1;

                this.draw();
                this.batchDrawSelectCanvas(this.batchSelectedCanvas);
                
                // this.canvasIndex = -1;
                if (this.canvasIndex < 0) return;
  
                this.maxScale()
            },
            //旋转
            rotation() {
                let v = this.pathList[this.canvasIndex]
                v.angle = v.angle + 30;
                this.draw()
            },
            // 批量绘制选中的
            batchDrawSelectCanvas(selectedCanvas = []) {
                selectedCanvas.forEach(v => {
                    this.drawSelectCanvasBorder(v);
                })
            },
            //绘画选中的canvas
            // canvasIndex不为-1的
            drawSelectCanvas() {
  
                //绘制一个左上
                if (this.canvasIndex < 0) return;
                let v = this.pathList[this.canvasIndex]
                this.drawSelectCanvasBorder(v);
            },
            drawSelectCanvasBorder(v) {
                if (v.module == 'B' && (v.type == 1 || v.type == 2)) v.h = v.fontSize + 6

                let ctx = this.ctx;

                ctx.beginPath()
                ctx.lineWidth = 1
                this.elementRotation(ctx, v)
                this.scale(ctx, v)
                let color = "#FF0000";
                let num = 6;
                let dd9 = 35
                ctx.strokeStyle = color;
                //绘制一个左上
                let d1 = v.x - num;
                //左中
                let d2 = (v.h / 2 + v.y) - num;
                //左下
                let dd3 = (v.h + v.y) - num
                //右上
                let d4 = (v.x + v.w) - num
                //右中
                let d5 = (v.h / 2 + v.y) - num;
                let dd6 = (v.h + v.y) - num
                //右下
                //下中
                let d7 = (v.x + v.w / 2) - num
                let dd7 = (v.h + v.y) - num
                let list = new Array()
                let rectList = [{
                        x: d1,
                        y: v.y - num
                    }, {
                        x: d1,
                        y: d2
                    },
                    {
                        x: d1,
                        y: dd3
                    }, {
                        x: d4,
                        y: v.y - num
                    }, {
                        x: d4,
                        y: d5
                    },
                    {
                        x: d4,
                        y: dd6
                    }, {
                        x: d7,
                        y: dd7
                    }, {
                        x: d7,
                        y: v.y - num
                    },

                ]


                rectList.forEach((vv, i) => {
                    let path = new Path2D();

                    ctx.beginPath()
                    // ctx.strokeStyle = "#063cff";
                    // ctx.fillStyle = "#063cff"
                    ctx.fillStyle = "#FFFFFF"
                    ctx.strokeStyle = "#0000FF"
                    ctx.lineWidth = 1
                    if (v.module == 'B') {
                        if (i == 1 || i == 4) {
                            path.rect(vv.x, vv.y, num * 2, num * 2);
                            ctx.stroke(path)
                            ctx.fillRect(vv.x, vv.y, num * 2, num * 2);

                        }
                    } else {
                        
                        // if(v.module=="A"&&v.type==4){
                        //     if (i == 6 || i == 7) {
                        //         path.rect(vv.x, vv.y, num * 2, num * 2);
                        //         ctx.stroke(path)
                        //         ctx.fillRect(vv.x, vv.y, num * 2, num * 2);
                            
                        //     }
                        // }else{
                        //     path.rect(vv.x, vv.y, num * 2, num * 2);
                        //     ctx.stroke(path)
                        //     ctx.fillRect(vv.x, vv.y, num * 2, num * 2);
                        // }
                        
                        path.rect(vv.x, vv.y, num * 2, num * 2);
                        ctx.stroke(path)
                        ctx.fillRect(vv.x, vv.y, num * 2, num * 2);
                    }
                    let key = {
                        x: vv.x,
                        y: vv.y,
                        w: num * 2,
                        h: num * 2
                    }
                    list.push(key)
                })
                this.selectSpot = list;
                ctx.rect(v.x, v.y, v.w, v.h);

                ctx.stroke();
                ctx.restore()
            },
            //取消浏览器默认行为
            preventDefault(e) {
                e = e || window.event;
  
                e.preventDefault && e.preventDefault(); //禁止浏览器默认事件//禁止浏览器默认事件
                e.stopPropagation()
            },
            //移动事件
            mouseMove(e) {
                this.preventDefault(e)
                let that = this;
                
                if (!that.isDown) {
                    if (that.spotCopy == -1) that.getSelectSpot(e)
                    that.getSelectSpot(e)
                    return;
                } else if (that.isDown && !this.batchSelectedCanvasEditing) {
                    this.draw();
                    let {
                        offsetX,
                        offsetY
                    } = e;
                    let rect = new Rect({
                        color: 'transparent',
                        startX: this.mouse.x,
                        startY: this.mouse.y,
                        canvasCtx: this.ctx,
                    });
                    rect.endX = offsetX;
                    rect.endY = offsetY;
                    rect.draw();

                    
                    this.pathList.forEach( c => {
                        if(c.module === 'A' || c.module === 'B') {
                            let cWidth = c.w;
                            if (c.module === 'B') {
                                cWidth = this.ctx.measureText(c.content).width - 40;
                            }
                            if (
                                c.x >= rect.minX &&
                                c.x + cWidth <= rect.maxX && 
                                c.y >= rect.minY &&
                                c.y + c.h <= rect.maxY
                            ) {
                                let batchMap = {};
                                this.batchSelectedCanvas.forEach( bc => {
                                    batchMap[bc.id] = true;
                                })
                                if (!batchMap[c.id]) {
                                    this.batchSelectedCanvas.push(c);
                                }
                            }
                        } else {
                            let batchMap = {};
                            this.batchSelectedCanvas.forEach( bc => {
                                batchMap[bc.id] = true;
                            })
                            if (batchMap[c.id]) {
                                this.batchSelectedCanvas = this.batchSelectedCanvas.filter(bc => bc.id != c.id );
                            }
                        }
                    })
                    this.batchDrawSelectCanvas(this.batchSelectedCanvas);
                    this.tempBatchSelectedCanvas = JSON.parse(JSON.stringify(this.batchSelectedCanvas));
                }
                if (this.batchSelectedCanvas.length > 0 && this.batchSelectedCanvasEditing) {
                    let {
                        offsetX,
                        offsetY
                    } = e;
                    this.batchSelectedCanvas.forEach((item, index) => {
                        let canvas = this.pathList.find(item2 => item.id === item2.id);
                        canvas.x = this.tempBatchSelectedCanvas[index].x + offsetX - that.mouse.x;
                        canvas.y = this.tempBatchSelectedCanvas[index].y + offsetY - that.mouse.y;
                        this.draw();
                        this.batchDrawSelectCanvas(this.batchSelectedCanvas);
                    });
                    return;
                }
                if (that.canvasIndex > -1) {
                    return this.moveCanvasInGraph(e, this.pathList[that.canvasIndex], true);
                }
  
            },
            // 移动画布上的元素
            // 参数是pathList的一项
            moveCanvasInGraph(e, canvas, showSupportLine) {
                let {
                    offsetX,
                    offsetY
                } = e;
                let that = this;
                if (that.spotCopy < 0 && that.spot < 0) {
                    if (that.canvasIndexCopy < 0) return;
                    let obj = canvas
                    obj.x = obj.x + (offsetX - that.mouse.x);
                    obj.y = obj.y + (offsetY - that.mouse.y);
                    that.XYWH = obj
                    that.draw();
                    that.mouse.x = offsetX;
                    that.mouse.y = offsetY;
  
                } else {
  
                    if (that.spotCopy != that.spot) return;
  
                    that.zoom(e)
                    that.draw();
                    that.mouse.x = offsetX;
                    that.mouse.y = offsetY;
                }

                //把(evt.offsetX,evt.offsetY)移动过程中的鼠标点作为矩形的中心
                // 添加，移动的时候画两条线
                if (showSupportLine && this.canvasIndex > -1) {
                    let {x, y, h} = this.pathList[this.canvasIndex];
                    this.ctx.strokeStyle = '#ff0000';
                    this.ctx.lineWidth = 0.5;
                    this.ctx.beginPath();
                    this.ctx.moveTo(x, 0);
                    this.ctx.lineTo(x, y);
                    this.ctx.moveTo(0, y);
                    this.ctx.lineTo(x, y);
                    this.ctx.moveTo(0, y + h);
                    this.ctx.lineTo(x, y + h);
                    this.ctx.stroke();
                }
            },
            zoom(e) {
  
                let v = this.pathList[this.canvasIndex];
                this.editCanvasBody = JSON.parse(JSON.stringify(v))
  
                let {
                    offsetX,
                    offsetY
                } = e;
                let b = ([3].indexOf(v.type) > -1 && v.module == 'A')
  
  
                let direction = mouseUp2(e)
                let vvw = v.x + v.w;
                let xx = Math.abs(v.x - offsetX)
  
                let yy = Math.abs(v.y - offsetY)

                // 1右 2下 3左 4上
                // 根据whRatio计算宽高， whRatio = w / h
                // 只修改二维码，条形码和上传图片
                let ratioScale = false;
                // 关闭缩放
                if (v.module == 'A' ) {
                    // 图片允许缩放
                    ratioScale = v.type == 7;
                }
                let condition = v.module == 'A' && (v.type == 5 || v.type == 6);
                if (condition) {
                    // 如果是图片条形码二维码，则关闭缩放
                    return;
                }
                switch (direction) {
                    case 1:
  
                        if (this.spotCopy == 1 || this.spotCopy == 0 || this.spotCopy == 2) {
                            if (b) {
                                v.r = v.r - xx / 2
                                v.w = 2 * v.r
                                v.h = 2 * v.r
                                v.x = v.x + xx
                                v.y = v.y + xx / 2
                            } else {
                                v.x = offsetX
                                v.w = vvw - offsetX;
                                if (v.w < 1) v.w = 1;
                                ratioScale && (v.h = v.w / v.whRatio);
                            }
  
                        }
                        if (this.spotCopy == 3 || this.spotCopy == 4 || this.spotCopy == 5) {
                            if (b) {
                                let x = offsetX - v.x - v.w
                                v.r = v.r + x / 2
                                v.w = 2 * v.r
                                v.h = 2 * v.r
  
                                v.y = v.y - x / 2
                            } else {
                                v.w = offsetX - v.x;
                                ratioScale && (v.h = v.w / v.whRatio);
                            }
                        }
                        break;
                    case 2:
  
                        if (this.spotCopy == 7 || this.spotCopy == 0 || this.spotCopy == 3) {
                            if (b) {
                                let yy = (offsetY - v.y)
                                v.r = v.r - yy / 2
                                v.y = v.y + yy
                                v.w = 2 * v.r
                                v.h = 2 * v.r
                                v.x = v.x + yy / 2
                            } else {
                                v.h = v.y + v.h - offsetY;
                                v.y = offsetY;
  
                                if (v.h < 1) v.h = 1;
                                ratioScale && (v.w = v.h * v.whRatio);
                            }
  
                        }
  
                        if (this.spotCopy == 6 || this.spotCopy == 2 || this.spotCopy == 5) {
                            if (b) {
                                let yy = (offsetY - v.h - v.y)
                                v.r = v.r + yy / 2
                                v.w = 2 * v.r
                                v.h = 2 * v.r
                                v.x = v.x - yy / 2
                            } else
                                v.h = offsetY - v.y;
                                ratioScale && (v.w = v.h * v.whRatio);
                        }
  
                        break;
                    case 3:
  
                        if (this.spotCopy == 1 || this.spotCopy == 0 || this.spotCopy == 2) {
                            if (b) {
                                v.r = v.r + xx / 2
                                v.w = 2 * v.r
                                v.h = 2 * v.r
                                v.x = v.x - xx
                                v.y = v.y - xx / 2
                            } else {
                                v.x = offsetX
                                v.w = vvw - offsetX;
                                ratioScale && (v.h = v.w / v.whRatio);
                            }
  
  
                        }
  
                        if (this.spotCopy == 3 || this.spotCopy == 4 || this.spotCopy == 5) {
                            if (b) {
                                let xx = v.x + v.w - offsetX
  
                                v.r = v.r - xx / 2
                                v.w = 2 * v.r
                                v.h = 2 * v.r
                                v.x = v.x
                                v.y = v.y + xx / 2
                            } else {
                                v.w = offsetX - v.x;
                                if (v.w < 1) v.w = 1;
                                ratioScale &&(v.h = v.w / v.whRatio);
                            }
  
                        }
                        break;
                    case 4:
  
                        if (this.spotCopy == 7 || this.spotCopy == 0 || this.spotCopy == 3) {
                            if (b) {
                                let yy = (offsetY - v.y)
                                v.r = v.r - yy / 2
                                v.y = v.y + yy
                                v.w = 2 * v.r
                                v.h = 2 * v.r
                                v.x = v.x + yy / 2
                            } else {
                                v.h = v.y + v.h - offsetY
                                v.y = offsetY;
                                ratioScale &&(v.w = v.h * v.whRatio);
                            }
  
  
                        }
                        if (this.spotCopy == 6 || this.spotCopy == 2 || this.spotCopy == 5) {
                            if (b) {
                                let yy = (offsetY - v.h - v.y)
                                v.r = v.r + yy / 2
                                v.w = 2 * v.r
                                v.h = 2 * v.r
                                v.x = v.x - yy / 2
                            } else {
                                v.h = offsetY - v.y
                                if (v.h < 1) v.h = 1;
                                ratioScale && (v.w = v.h * v.whRatio);
                            }
  
  
                        }
  
                        break;
  
                }
  
            },
            //按下事件
            async mousedown(e) {
                this.preventDefault(e)
                // this.batchSelectedCanvas = [];
                this.draw();
                await this.$nextTick();
                mouseDown2(e)
                this.isDown = true;
                if (this.spotCopy < 0) this.judgeIsPointInPath(e)
                this.draw(e);
            },
            //绘制条形码
            drawBarCode(v) {
                let ctx = this.ctx;
                this.elementRotation(ctx, v)
                this.scale(ctx, v)
                let image = document.getElementById("barCode")
                ctx.drawImage(image, v.x, v.y, v.w, v.h)
                ctx.restore()
            },
            //绘制二维码
            drawQrCode(v) {
                let ctx = this.ctx;
                this.elementRotation(ctx, v)
                this.scale(ctx, v)
                // let image = document.getElementById("qrCode")
                // ctx.drawImage(image, v.x, v.y, v.w, v.h)
                let qrVersion = getQRCodeVersion({
                    ECLevel: 2,
                    mode: 4,
                    text: toUtf8(v.content)
                });
                let nModule = nModulesFromVersion(qrVersion);
                document.querySelector('#qrCode').innerHTML = '';
                let imgW = nModule * (v.moduleSize || 5);
                jQuery('#qrCode').qrcode({
                    width: imgW,
                    height: imgW,
                    mode: 4,
                    correctLevel:0,
                    text: toUtf8(v.content),
                    render: 'canvas',
                    bgColor: '#ffff00',
                    moduleColor: '#0000ff',
                    moduleSize: v.moduleSize || 5,
                });
                ctx.drawImage(document.querySelector('#qrCode canvas'), v.x, v.y, imgW, imgW);
                v.w = imgW;
                v.h = imgW;
                v.whRatio = 1;
                ctx.restore()
            },
            //绘制基础控件
            drawMoudleA(v) {
                switch (v.type) {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                        this.drawRoundRect(v)
                        break;
                    case 5:
                        this.drawQrCode(v)
                        break;
                    case 6:
                        this.drawBarCode(v)
                        break;
                    case 7:
                        this.drawImage(v, true);
                        break;
                }
            },
            drawMoudleB(v) {
                switch (v.type) {
                    case 1:
                        this.drawEmptyText(v)
                        break;
                    case 2:
                        this.drawEmptyText(v);
                    case 3:
                        this.drawEmptyText(v);
                    case 4:
                        this.drawEmptyText(v);
                }
            },
            //区分绘制canvas
            drawCase(v) {
                switch (v.module) {
                    case 'A':
                        this.drawMoudleA(v)
                        break;
                    case 'B':
                        this.drawMoudleB(v)
                        break;
                }
            },
  
            judgeIsPointInPath(e) {
                let ctx = this.ctx;
                ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
                ctx.restore()
                let {
                    offsetX,
                    offsetY
                } = e;
                this.mouse.x = offsetX;
                this.mouse.y = offsetY;
                let index = -1
                let arrList = this.pathList;
                for (let i = arrList.length - 1; i >= 0; i--) {
                    let v = arrList[i]
  
                    ctx.beginPath()
                    this.elementRotation(ctx, v)
                    this.scale(ctx, v)
                    ctx.rect(v.x, v.y, v.w, v.h)
                    ctx.stroke()
  
                    if (ctx.isPointInPath(offsetX, offsetY)) {
                        index = i
                        this.drawSelectCanvas()
                        break;
                    } else {
                        // 取消选中
                        this.canvasIndex = -1;
                    }
                    ctx.closePath();
                    ctx.restore()
                }
                if (!this.previewImg) {
                    this.drawGrid(ctx, this.canvasWidth, this.canvasHeight, this.canvasGridC, this.canvasGridW,
                        this
                        .canvasGridH)
  
                }
  
  
                if (index > -1 && this.batchSelectedCanvas.length == 0) {
                    this.batchSelectedCanvasEditing = false;
                    this.canvasIndex = index;
                    let v = this.pathList[this.canvasIndex]
                    this.editCanvasBody = v
                    this.XYWH = v;
                    if( this.lastClickItemIdx == index && v.module == 'B') {
                        this.clickItem3times += 1;
                        let { offsetLeft, offsetTop } = this.$refs.canvasRef;
                        this.canvasIpt.w = v.w;
                        this.canvasIpt.h = v.h;
                        this.canvasIpt.l = v.x + offsetLeft;
                        this.canvasIpt.t = v.y + offsetTop;
                    } else {
                        this.clickItem3times = 1;
                        this.lastClickItemIdx = index;
                    }
                } else if (index > -1 && this.batchSelectedCanvas.length > 0) {
                    this.batchSelectedCanvasEditing = true;
                } else if (index === -1 && this.batchSelectedCanvas.length > 0) {
                    this.batchSelectedCanvasEditing = false;
                    this.batchSelectedCanvas = [];
                    this.draw();
                    this.batchDrawSelectCanvas(this.pathList);
                } else if (index === -1) {
                    this.clickItem3times = 0;
                    this.lastClickItemIdx = 0;
                }
  
                this.canvasIndexCopy = index;
  
                return index;
  
            },
            maxScale() {
                if (this.canvasIndex < 0) return;
                let v = this.pathList[this.canvasIndex]
                if (this.isDown) {
  
                    v.scale += 0.1
                } else {
                    v.scale = 1;
  
                }
  
                this.draw()
  
            },
            minScale() {
                if (this.canvasIndex < 0) return;
                let v = this.pathList[this.canvasIndex]
  
                if (this.isDown) {
                    if (v.scale > 0.2) {
                        v.scale -= 0.1
  
                    } else {
                        v.scale = 0.1;
                    }
                } else {
                    v.scale = 1;
                }

  
                this.draw()
            },
            //元素旋转
            elementRotation(ctx, v) {
                ctx.save();
                let x = v.x + .5 * v.w
                let y = v.y + .5 * v.h
                ctx.translate(x, y)
  
                ctx.rotate(Math.PI / 180 * v.angle)
  
                ctx.translate(-x, -y)
            },
  
            //清空
            clearCanvas() {
                this.pathList = []
                this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
                this.canvasIndex = -1;
                let ctx = this.ctx;
                this.drawGrid(ctx, this.canvasWidth, this.canvasHeight, this.canvasGridC, this.canvasGridW, this
                    .canvasGridH)
                this.editCanvasBody.other = ''
            },
            saveAsBmp() {
                window.$c2i.saveAsImage(this.ctx.canvas, this.canvasWidth, this.canvasHeight, 'bmp')
            },
            exportAsJSON() {
                let color = "black_white_red";
                if ( this.params.type == 0) {
                    color = "black_white";
                }
                if ( this.params.type == 2 ) {
                    color = "black_white_yellow"
                }
                let pathList = JSON.parse(JSON.stringify(this.pathList));
                pathList.forEach(item => {
                    if ( item.module == 'B' && item.valueType == 'text') {
                        item.family += '.ttf'
                        item.varName && (item.isVar = true);
                        !item.varName && (item.isVar = false);
                    }
                    delete item.fromServer;

                })
                let data = {
                    "templateCode": this.params.templateCode,
                    "background_color": "white",
                    "color": color,
                    "dataSource": "priSmart",
                    "direction": "0",
                    "height": this.canvasHeight,
                    "originDirection": 90,
                    "overlap_rule": "order_wise",
                    "size": this.params.screenSize,
                    "width": this.canvasWidth,
                    "screen_block": pathList
                };
                let json = JSON.stringify(data, null, 4);
                let a = document.createElement('a');
                a.download = '画布.json';
                a.style.display = 'none';
                let blob = new Blob([json], {
                    type: 'application/json'
                });
                a.href = URL.createObjectURL(blob);
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            },
            canvasUndo() {
                this.crtUndoIndex -= 1;
                if (this.crtUndoIndex <= 0) {
                    this.crtUndoIndex = 0;
                }
                this.pathList = JSON.parse(JSON.stringify(this.undoStock[this.crtUndoIndex]));
                this.draw();
            },
            canvasForward() {
                this.crtUndoIndex += 1;
                this.pathList = JSON.parse(JSON.stringify(this.undoStock[this.crtUndoIndex]));
                this.draw();
            },
            draw(e) {
                let ctx = this.ctx;
                ctx.clearRect(0, 0, this.canvasWidth + 1, this.canvasHeight + 1)
                ctx.fillStyle = "rgba(255,255,255,1)"
                ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight)
                ctx.restore()
                let arrList = this.pathList;
                arrList.forEach((v, i) => {
                    this.drawCase(v)
                })
                if (!this.previewImg) {
                    this.drawGrid(ctx, this.canvasWidth, this.canvasHeight, this.canvasGridC, this.canvasGridW,
                        this
                        .canvasGridH)
                    this.drawSelectCanvas()
                }
  
            },
            drawGrid(ctx, canvasW, canvasH, color, stepx, stepy) {
  
                ctx.save();
                ctx.strokeStyle = color;
                ctx.lineWidth = 0.5;
                ctx.fillStyle = 'transparent';
                ctx.fillRect(0, 0, canvasW, canvasH);
                //画竖线
                for (var i = stepx + 0.5; i < canvasW; i += stepx) {
                    ctx.beginPath();
                    ctx.moveTo(i, 0);
                    ctx.lineTo(i, canvasH);
                    ctx.stroke();
                }
                //画横线
                for (var i = stepx + 0.5; i < canvasH; i += stepy) {
                    ctx.beginPath();
                    ctx.moveTo(0, i);
                    ctx.lineTo(canvasW, i);
                    ctx.stroke();
                }
                ctx.restore();
            },
            getDrawIcon() {
                let qrImg = this.getQrcodeImage()
                let doc = document.getElementById("qrCode")
                doc.src = qrImg
                let barImg = this.getBarCode()
                let doc2 = document.getElementById("barCode")
                doc2.src = barImg
                const ctx = document.getElementById('iconRect').getContext('2d')
                ctx.beginPath();
                ctx.lineWidth = 3
                ctx.rect(0, 0, 32, 32)
                ctx.stroke();
                const ctx2 = document.getElementById('iconRoundRect').getContext('2d')
                ctx2.beginPath();
                ctx2.lineWidth = 3
                this.createRoundRect(ctx2, 32, 32, 10, 0, 0)
                ctx2.stroke();
                const ctx3 = document.getElementById('iconArc').getContext('2d')
                ctx3.beginPath();
                ctx3.lineWidth = 2
                ctx3.arc(16, 16, 15, 0, 360 * Math.PI);
                ctx3.stroke();
                const ctx4 = document.getElementById('iconLine').getContext('2d')
                ctx4.beginPath();
                ctx4.moveTo(0, 16);
                ctx4.lineTo(32, 16);
                ctx4.stroke();
  
  
                let image = new Image();
                let imageUrl = this.getQrcodeUrl();
                image.src = imageUrl
                let image2 = new Image();
                let imageUrl2 = this.getBarcodeUrl();
                image2.src = imageUrl2

                const ctx5 = document.getElementById('iconQrCode').getContext('2d')
                const ctx6 = document.getElementById('iconBarCode').getContext('2d')

                // // 加载文本数字日期时间的图片
                // let image3 = new Image();
                // image3.src = require("@/assets/text.png");
                // image3.onload = () => {
                //     const ctx7 = document.getElementById("iconTextCode").getContext('2d')
                //     ctx7.drawImage(image3, 0, 0, 32, 32);
                // }

                //image.onload为异步加载
                image.onload = () => {
  
                    ctx5.drawImage(image, 0, 0, 32, 32);
                    ctx6.drawImage(image2, 0, 0, 32, 32);
                }
  
                let dc = document.getElementById("canvas")
                var tempSrc = dc.toDataURL("image/png");
                this.url = tempSrc
  
  
            }
        },
        created() {
  
        },
        mounted() {
            // 初始化画布参数
            this.initGraphParams();
            this.getRulerLeftVal();
            // dnd的拖拽事件
            this.$dragging.$on("dragged", (result) => {
                // 将排序后的结果重新赋值
                result.value.list.forEach((item, index) => {
                    item.index = index;
                })
                this.pathList = result.value.list;
                this.draw();
            });

            //鼠标移开事件
  
            this.getDrawIcon()
            const canvas = document.getElementById('canvas')
            this.ctx = canvas.getContext('2d')
            let ctx = this.ctx
  
  
            let that = this;
            document.fonts.ready.then(function() {
                that.draw()
                ctx.beginPath();
                ctx.fillStyle = "#000"
                // 写字
                ctx.font = "36px SourceHanSansK-Bold";
                // ctx.fillText("分", 10, 50);
                ctx.restore();
                ctx.closePath();
            })

            document.addEventListener('keyup', e => {
                this.handleKeyUp(e);
            })

            document.addEventListener('keydown', e => {
                this.handleKeyDown(e);
            })

            document.addEventListener('mousewheel', evt => {
                let ele = this.ctx.canvas;
                let zoom = parseInt(ele.style.zoom, 10) || 100;
                zoom += evt.wheelDelta / 12;
                if(zoom > 0) { 
                    ele.style.zoom = `${zoom}%`
                    this.$refs.topRulerRef.$el.style.zoom = `${zoom}%`
                    this.$refs.topRulerBoxRef.style.width = `${ this.canvasWidth * zoom / 100 }px`
                    this.$refs.ctxTopDivRef.style.zoom = `${ zoom }%`;
                    // this.$refs.topRulerRef.$el.parentElement.style.width = `${this.canvasWidth * zoom / 100 }px`
                    this.$refs.leftRulerRef.$el.style.zoom = `${zoom}%`
                    this.$refs.leftRulerRef.$el.parentElement.style.top = `${ 46 * zoom / 100 }px`;
                    this.$refs.leftRulerRef.$el.style.marginTop = `${ 0 }px`;
                    this.$refs.leftRulerBoxRef.style.height = `${ (this.canvasHeight + 10) * zoom / 100 - 5 }px`; 
                    // this.leftRulerBoxRef = `${ 0 }px`;
                    // this.$refs.leftRulerBoxRef.style.width = `${ 36 * (1 - zoom / 100) }px`;
                    // this.$refs.leftRulerRef.$el.style.left = `${ 34 * (1 - zoom / 100) }px`;
                }
            })
        }
    }
    var MouseY = 0,
        MouseX = 0,
        changeX = 0,
        changeY = 0;
    var X = 0,
        Y = 0;
  
    function mouseDown2(ev) {
        var Event = ev || event;
  
        MouseX = Event.clientX;
  
        MouseY = Event.clientY;
    }
  
    function mouseUp2(ev) {
        let index = 0;
        var Event = ev || event;
        changeX = Event.clientX;
        changeY = Event.clientY;
  
        X = changeX - MouseX;
        Y = changeY - MouseY;
  
        if ((((X > 0 && Y < 0) && (X > Math.abs(Y))) || (X > 0 && Y > 0 && X > Y) || (X > 0 && Y == 0))) { //右移动
  
  
            index = 1
  
        } else if (((Y > 0 && X < 0) && (Y > Math.abs(X))) || (Y > 0 && X > 0 && Y > X) || (Y > 0 && X == 0)) { //下移动
  
            index = 2
        } else if (((X < 0 && Y > 0) && (Math.abs(X) > Y)) || ((X < 0 && Y < 0) && (Math.abs(X) > Math.abs(Y))) || (X <
                0 && Y == 0)) { //左移动
  
            index = 3
        } else if (((Y < 0 && X < 0) && Math.abs(Y) > Math.abs(X)) || ((Y < 0 && X > 0) && (Math.abs(Y) > X)) || (Y <
                0 &&
                X == 0)) { //上移动
  
            index = 4
        } else if (X == 0 && Y == 0) {
  
        }
        MouseX = Event.clientX;
        MouseY = Event.clientY;
        return index;
    }
  </script>
  <!-- Add "scoped" attribute to limit CSS to this component only -->
  
  <style lang="less" scoped>
    /* 自定义字体 */
    /* @import url("../assets/fonts/font.css"); */
  
    ::v-deep .property_div .font_style {
        padding: 5px 5px !important;
    }
  
    .property_div {
        height: 100%;
        // width: 155px;
        float: left;
    }
  
    .identity-input {
        text-align: center;
  
    }
  
    .identity-input2 {
        text-align: center;
  
    }
  
    .property {
        height: 100%;
        width: 120px;
        float: left;
        padding-left: 5px;
        font-size: 14px;
        line-height: 25px;
    }
  
    .XYWH {
        height: 38px;
        width: 38px;
        float: left;
        text-align: center;
    }
  
    .XYWH div input {
        width: 25px;
        height: 20px;
    }
  
    .context {
        padding: 10px !important;
        font-family: "";
        // height: calc(100% - 20px);
        box-sizing: border-box;
        height: 100vh;
    }
  
    #canvas {
        background: #FFFFFF !important;
        border: 1px solid transparent;
    }
  
    .el-row {
        margin-bottom: 20px;
  
    }
  
    .el-row:last-child {
        margin-bottom: 0;
    }
  
    .el-col {
        border-radius: 4px;
    }
  
    .bg-purple-dark {
        background: #99a9bf;
    }
  
    .bg-purple {
        background: #d3dce6;
    }
  
    .bg-purple-light {
        background: #e5e9f2;
    }
  
    .grid-content {
        border-radius: 4px;
        min-height: 36px;
    }
  
    .row-bg {
        padding: 10px 0;
        background-color: #f9fafc;
    }
  
    ::v-deep .el-collapse-item__content {
        padding-bottom: 0px !important;
    }
  
    .base_contro {
        width: 25%;
        text-align: center;
        height: 60px;
        float: left;
        cursor: pointer;
  
    }
  
    .context {
        background: #e8e8e8 !important;
    }
  
    .dynamic_data {
        width: 80px;
        text-align: center;
        height: 40px;
        float: left;
        cursor: pointer;
  
    }
  
    .base_contro_icon {
        display: block;
        width: 100%;
        text-align: center;
    }
  
    .drawImg {
        // display: none;
        position: absolute;
        left: 100vh;
        opacity: 0;
    }
  
    ::v-deep .my_content .el-tabs__content {
        height: calc(100% - 60px) !important;
        overflow: auto !important;
    }

    ::v-deep {
        .el-date-editor.el-input, .el-date-editor.el-input__inner  {
            width: 150px;
        }
    }
  </style>
  